VirtualBox

source: vbox/trunk/src/VBox/Main/darwin/iokit.cpp@ 2433

Last change on this file since 2433 was 2342, checked in by vboxsync, 18 years ago

Export missing OS X stuff to OSE.

  • Property svn:eol-style set to native
File size: 7.1 KB
Line 
1/** $Id: $ */
2/** @file
3 * Main - Darwin IOKit Routines.
4 *
5 * Because IOKit makes use of COM like interfaces, it does not mix very
6 * well with COM/XPCOM and must therefore be isolated from it using a
7 * simpler C interface.
8 */
9
10/*
11 * Copyright (C) 2006 InnoTek Systemberatung GmbH
12 *
13 * This file is part of VirtualBox Open Source Edition (OSE), as
14 * available from http://www.virtualbox.org. This file is free software;
15 * you can redistribute it and/or modify it under the terms of the GNU
16 * General Public License as published by the Free Software Foundation,
17 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
18 * distribution. VirtualBox OSE is distributed in the hope that it will
19 * be useful, but WITHOUT ANY WARRANTY of any kind.
20 *
21 * If you received this file as part of a commercial VirtualBox
22 * distribution, then only the terms of your commercial VirtualBox
23 * license agreement apply instead of the previous paragraph.
24 */
25
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include <mach/mach.h>
31#include <Carbon/Carbon.h>
32#include <IOKit/IOKitLib.h>
33#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
34#include <IOKit/scsi-commands/SCSITaskLib.h>
35#include <mach/mach_error.h>
36
37#include <iprt/mem.h>
38#include <iprt/string.h>
39#include <iprt/assert.h>
40
41#include "iokit.h"
42
43
44/*******************************************************************************
45* Global Variables *
46*******************************************************************************/
47/** The IO Master Port. */
48static mach_port_t g_MasterPort = NULL;
49
50
51
52/**
53 * Enumerate the DVD drives returning a FIFO of device name strings.
54 *
55 * @returns Pointer to the head.
56 * The caller is responsible for calling RTMemFree() on each of the nodes.
57 */
58PDARWINDVD DarwinGetDVDDrives(void)
59{
60 PDARWINDVD pHead = NULL;
61 PDARWINDVD pTail = NULL;
62
63 /*
64 * Open the master port on the first invocation.
65 */
66 if (!g_MasterPort)
67 {
68 kern_return_t krc = IOMasterPort(MACH_PORT_NULL, &g_MasterPort);
69 AssertReturn(krc == KERN_SUCCESS, NULL);
70 }
71
72 /*
73 * Create a matching dictionary for searching for DVD services in the IOKit.
74 *
75 * [If I understand this correctly, plain CDROMs doesn't show up as
76 * IODVDServices. Too keep things simple, we will only support DVDs
77 * until somebody complains about it and we get hardware to test it on.
78 * (Unless I'm much mistaken, there aren't any (orignal) intel macs with
79 * plain cdroms.)]
80 */
81 CFMutableDictionaryRef RefMatchingDict = IOServiceMatching("IODVDServices");
82 AssertReturn(RefMatchingDict, NULL);
83
84 /*
85 * do the search and get a collection of keyboards.
86 */
87 io_iterator_t DVDServices = NULL;
88 IOReturn rc = IOServiceGetMatchingServices(g_MasterPort, RefMatchingDict, &DVDServices);
89 AssertMsgReturn(rc == kIOReturnSuccess, ("rc=%d\n", rc), NULL);
90 RefMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */
91
92 /*
93 * Enumerate the DVD drives (services).
94 * (This enumeration must be identical to the one performed in DrvHostBase.cpp.)
95 */
96 unsigned i = 0;
97 io_object_t DVDService;
98 while ((DVDService = IOIteratorNext(DVDServices)) != 0)
99 {
100 /*
101 * Get the properties we use to identify the DVD drive.
102 *
103 * While there is a (weird 12 byte) GUID, it isn't persistent
104 * accross boots. So, we have to use a combination of the
105 * vendor name and product name properties with an optional
106 * sequence number for identification.
107 */
108 CFMutableDictionaryRef PropsRef = 0;
109 kern_return_t krc = IORegistryEntryCreateCFProperties(DVDService, &PropsRef, kCFAllocatorDefault, kNilOptions);
110 if (krc == KERN_SUCCESS)
111 {
112 /* Get the Device Characteristics dictionary. */
113 CFDictionaryRef DevCharRef = (CFDictionaryRef)CFDictionaryGetValue(PropsRef, CFSTR(kIOPropertyDeviceCharacteristicsKey));
114 if (DevCharRef)
115 {
116 /* The vendor name. */
117 char szVendor[128];
118 char *pszVendor = &szVendor[0];
119 CFTypeRef ValueRef = CFDictionaryGetValue(DevCharRef, CFSTR(kIOPropertyVendorNameKey));
120 if ( ValueRef
121 && CFGetTypeID(ValueRef) == CFStringGetTypeID()
122 && CFStringGetCString((CFStringRef)ValueRef, szVendor, sizeof(szVendor), kCFStringEncodingUTF8))
123 pszVendor = RTStrStrip(szVendor);
124 else
125 *pszVendor = '\0';
126
127 /* The product name. */
128 char szProduct[128];
129 char *pszProduct = &szProduct[0];
130 ValueRef = CFDictionaryGetValue(DevCharRef, CFSTR(kIOPropertyProductNameKey));
131 if ( ValueRef
132 && CFGetTypeID(ValueRef) == CFStringGetTypeID()
133 && CFStringGetCString((CFStringRef)ValueRef, szProduct, sizeof(szProduct), kCFStringEncodingUTF8))
134 pszProduct = RTStrStrip(szProduct);
135 else
136 *pszProduct = '\0';
137
138 /* Construct the name and check for duplicates. */
139 char szName[256 + 32];
140 if (*pszVendor || *pszProduct)
141 {
142 if (*pszVendor && *pszProduct)
143 RTStrPrintf(szName, sizeof(szName), "%s %s", pszVendor, pszProduct);
144 else
145 strcpy(szName, *pszVendor ? pszVendor : pszProduct);
146
147 for (PDARWINDVD pCur = pHead; pCur; pCur = pCur->pNext)
148 {
149 if (!strcmp(szName, pCur->szName))
150 {
151 if (*pszVendor && *pszProduct)
152 RTStrPrintf(szName, sizeof(szName), "%s %s (#%u)", pszVendor, pszProduct, i);
153 else
154 RTStrPrintf(szName, sizeof(szName), "%s %s (#%u)", *pszVendor ? pszVendor : pszProduct, i);
155 break;
156 }
157 }
158 }
159 else
160 RTStrPrintf(szName, sizeof(szName), "(#%u)", i);
161
162 /* Create the device. */
163 size_t cbName = strlen(szName) + 1;
164 PDARWINDVD pNew = (PDARWINDVD)RTMemAlloc(RT_OFFSETOF(DARWINDVD, szName[cbName]));
165 if (pNew)
166 {
167 pNew->pNext = NULL;
168 memcpy(pNew->szName, szName, cbName);
169 if (pTail)
170 pTail = pTail->pNext = pNew;
171 else
172 pTail = pHead = pNew;
173 }
174 }
175 CFRelease(PropsRef);
176 }
177 else
178 AssertMsgFailed(("krc=%#x\n", krc));
179
180 IOObjectRelease(DVDService);
181 i++;
182 }
183
184 IOObjectRelease(DVDServices);
185
186 return pHead;
187}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette