//--------------------------------------------------------------------------- // Code //--------------------------------------------------------------------------- XN_DDK_API XnStatus XnStreamDataCreateNoBuffer(XnStreamData** ppStreamOutput, const XnChar* StreamName) { XN_VALIDATE_OUTPUT_PTR(ppStreamOutput); // allocate struct XN_VALIDATE_CALLOC(*ppStreamOutput, XnStreamData, 1); XnStreamData* pStreamOutput = *ppStreamOutput; // allocate internal data pStreamOutput->pInternal = (XnStreamDataInternal*)xnOSCalloc(1, sizeof(XnStreamDataInternal)); if (pStreamOutput->pInternal == NULL) { XnStreamDataDestroy(ppStreamOutput); return (XN_STATUS_ALLOC_FAILED); } // fill internal data pStreamOutput->pInternal->bAllocated = FALSE; pStreamOutput->pInternal->nAllocSize = 0; pStreamOutput->pInternal->UpdateMode = XN_STREAM_DATA_UPDATE_AUTOMATICALLY; pStreamOutput->pInternal->Callback = NULL; pStreamOutput->pInternal->pLockedBuffer = NULL; // take name xnOSStrCopy(pStreamOutput->StreamName, StreamName, XN_DEVICE_MAX_STRING_LENGTH); return (XN_STATUS_OK); }
XN_C_API XnStatus xnOSCreateNamedMutex(XN_MUTEX_HANDLE* pMutexHandle, const XnChar* cpMutexName) { // Local function variables XnStatus nRetVal = XN_STATUS_OK; int rc = 0; // Validate the input/output pointers (to make sure none of them is NULL) XN_VALIDATE_OUTPUT_PTR(pMutexHandle); XnMutex* pMutex; XN_VALIDATE_CALLOC(pMutex, XnMutex, 1); pMutex->bIsNamed = TRUE; nRetVal = xnOSNamedMutexCreate(pMutex, cpMutexName); if (nRetVal != XN_STATUS_OK) { xnOSFree(pMutex); return (nRetVal); } *pMutexHandle = pMutex; // All is good... return (XN_STATUS_OK); }
XN_C_API XnStatus xnSchedulerStart(XnScheduler** ppScheduler) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_OUTPUT_PTR(ppScheduler); *ppScheduler = NULL; // allocate handle XnScheduler* pScheduler = NULL; XN_VALIDATE_CALLOC(pScheduler, XnScheduler, 1); // create event nRetVal = xnOSCreateEvent(&pScheduler->hWakeThreadEvent, FALSE); XN_CHECK_RC_AND_FREE(nRetVal, pScheduler); // create critical section nRetVal = xnOSCreateCriticalSection(&pScheduler->hCriticalSection); XN_CHECK_RC_AND_FREE(nRetVal, pScheduler); // start thread nRetVal = xnOSCreateThread(xnSchedulerThreadFunc, (XN_THREAD_PARAM)pScheduler, &pScheduler->hThread); XN_CHECK_RC_AND_FREE(nRetVal, pScheduler); *ppScheduler = pScheduler; return (XN_STATUS_OK); }
XN_C_API XnStatus xnProfilingInit(XnUInt32 nProfilingInterval) { XnStatus nRetVal = XN_STATUS_OK; if (nProfilingInterval == 0) { xnProfilingShutdown(); } else if (!g_ProfilingData.bInitialized) { g_ProfilingData.nMaxSectionName = 0; g_ProfilingData.nSectionCount = 0; g_ProfilingData.nProfilingInterval = nProfilingInterval; g_ProfilingData.bKillThread = FALSE; XN_VALIDATE_CALLOC(g_ProfilingData.aSections, XnProfiledSection, MAX_PROFILED_SECTIONS); g_ProfilingData.nSectionCount = 0; nRetVal = xnOSCreateThread(xnProfilingThread, (XN_THREAD_PARAM)NULL, &g_ProfilingData.hThread); XN_IS_STATUS_OK(nRetVal); nRetVal = xnOSCreateCriticalSection(&g_ProfilingData.hCriticalSection); XN_IS_STATUS_OK(nRetVal); g_ProfilingData.bInitialized = TRUE; } return XN_STATUS_OK; }
XN_C_API XnStatus xnEnumerateLicenses(XnContext* pContext, XnLicense** paLicenses, XnUInt32* pnCount) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_INPUT_PTR(pContext); XN_VALIDATE_OUTPUT_PTR(paLicenses); XN_VALIDATE_OUTPUT_PTR(pnCount); *paLicenses = NULL; *pnCount = 0; XnUInt32 nCount = pContext->pLicenses->Size(); // allocate list XnLicense* pList; XN_VALIDATE_CALLOC(pList, XnLicense, nCount); // copy data XnUInt32 i = 0; for (XnLicenseList::ConstIterator it = pContext->pLicenses->begin(); it != pContext->pLicenses->end(); ++it, ++i) { pList[i] = *it; } // return to caller *paLicenses = pList; *pnCount = nCount; return (XN_STATUS_OK); }
XN_C_API XnStatus xnOSCreateEvent(XN_EVENT_HANDLE* pEventHandle, XnBool bManualReset) { XN_EVENT_HANDLE hEvent; XN_VALIDATE_CALLOC(hEvent, _XnEvent, 1); hEvent->bManual = bManualReset; *pEventHandle = hEvent; return (XN_STATUS_OK); }
XN_C_API XnStatus xnNodeQueryAllocate(XnNodeQuery** ppQuery) { XN_VALIDATE_OUTPUT_PTR(ppQuery); XN_VALIDATE_CALLOC(*ppQuery, XnNodeQuery, 1); (*ppQuery)->MaxVersion.nMajor = 0xFF; return (XN_STATUS_OK); }
XN_C_API XnStatus xnEnumerationErrorsAllocate(XnEnumerationErrors** ppError) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_OUTPUT_PTR(ppError); XN_VALIDATE_CALLOC(*ppError, XnEnumerationErrors, 1); return (XN_STATUS_OK); }
XN_C_API XnStatus xnOSCreateSharedMemory(const XnChar* strName, XnUInt32 nSize, XnUInt32 nAccessFlags, XN_SHARED_MEMORY_HANDLE* phSharedMem) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_INPUT_PTR(strName); XN_VALIDATE_OUTPUT_PTR(phSharedMem); DWORD mapflags; nRetVal = AccessFlagsToWin32MapFlags(nAccessFlags, &mapflags); XN_IS_STATUS_OK(nRetVal); DWORD viewflags; nRetVal = AccessFlagsToWin32ViewFlags(nAccessFlags, &viewflags); XN_IS_STATUS_OK(nRetVal); XnChar strWinName[XN_FILE_MAX_PATH]; nRetVal = NameToWin32Name(strName, strWinName); XN_IS_STATUS_OK(nRetVal); // allocate handle XnOSSharedMemory* pHandle; XN_VALIDATE_CALLOC(pHandle, XnOSSharedMemory, 1); // create file mapping pHandle->hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file NULL, // default security mapflags, // read/write access 0, // max. object size nSize, // buffer size strWinName); // name of mapping object if (pHandle->hMapFile == NULL) { XN_LOG_ERROR_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not create file mapping object (%d).", GetLastError()); } // map it to the process pHandle->pAddress = MapViewOfFile( pHandle->hMapFile, // handle to map object viewflags, // read/write permission 0, 0, nSize); if (pHandle->pAddress == NULL) { XN_LOG_ERROR_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not map view of file (%d).", GetLastError()); } *phSharedMem = pHandle; return (XN_STATUS_OK); }
XN_C_API XnStatus XN_C_DECL xnOSOpenSharedMemoryEx(const XnChar* strName, XnUInt32 nAccessFlags, XnBool bAllowOtherUsers, XN_SHARED_MEMORY_HANDLE* phSharedMem) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_INPUT_PTR(strName); XN_VALIDATE_OUTPUT_PTR(phSharedMem); DWORD flags; nRetVal = AccessFlagsToWin32ViewFlags(nAccessFlags, &flags); XN_IS_STATUS_OK(nRetVal); XnChar strWinName[XN_FILE_MAX_PATH]; nRetVal = XnWin32CreateKernelObjectName(strWinName, MAX_PATH, strName, bAllowOtherUsers); if (nRetVal != XN_STATUS_OK) { return XN_STATUS_OS_FAILED_TO_OPEN_SHARED_MEMORY; } // allocate handle XnOSSharedMemory* pHandle; XN_VALIDATE_CALLOC(pHandle, XnOSSharedMemory, 1); // create file mapping pHandle->hMapFile = OpenFileMapping( flags, // read/write access FALSE, // do not inherit the name strWinName); // name of mapping object if (pHandle->hMapFile == NULL) { XN_LOG_ERROR_RETURN(XN_STATUS_OS_FAILED_TO_OPEN_SHARED_MEMORY, XN_MASK_OS, "Could not open file mapping object (%d).", GetLastError()); } // map it to the process pHandle->pAddress = MapViewOfFile( pHandle->hMapFile, // handle to map object flags, // read/write permission 0, 0, 0); if (pHandle->pAddress == NULL) { XN_LOG_ERROR_RETURN(XN_STATUS_OS_FAILED_TO_OPEN_SHARED_MEMORY, XN_MASK_OS, "Could not map view of file (%d).", GetLastError()); } *phSharedMem = pHandle; return (XN_STATUS_OK); }
//--------------------------------------------------------------------------- // Code //--------------------------------------------------------------------------- XnStatus xnFPSInit(XnFPSData* pFPS, XnUInt32 nSamplesCount) { XN_VALIDATE_OUTPUT_PTR(pFPS); // Allocate struct XN_VALIDATE_CALLOC(*pFPS, XnFPSDataImpl, 1); XnFPSDataImpl* pData = *pFPS; // Allocate array XN_VALIDATE_ALIGNED_CALLOC(pData->anTimes, XnUInt64, nSamplesCount, XN_DEFAULT_MEM_ALIGN); pData->nArraySize = nSamplesCount; return XN_STATUS_OK; }
XnStatus XnExportedSensorDevice::EnumerateProductionTrees(xn::Context& context, xn::NodeInfoList& TreesList, xn::EnumerationErrors* /*pErrors*/) { XnStatus nRetVal = XN_STATUS_OK; // enumerate connected sensors XnUInt32 nCount = 0; // check if sensor is connected nRetVal = XnSensor::Enumerate(NULL, &nCount); if (nRetVal != XN_STATUS_OUTPUT_BUFFER_OVERFLOW) { // no sensor connected return XN_STATUS_DEVICE_NOT_CONNECTED; } // allocate according to count XnConnectionString* pConnStrings; XN_VALIDATE_CALLOC(pConnStrings, XnConnectionString, nCount); nRetVal = XnSensor::Enumerate(pConnStrings, &nCount); if (nRetVal != XN_STATUS_OK) { xnOSFree(pConnStrings); return (nRetVal); } XnProductionNodeDescription Description; GetDescription(&Description); for (XnUInt32 i = 0; i < nCount; ++i) { // Each connection string is a sensor. Return it if it wasn't created already. if (FindCreatedDevice(context.GetUnderlyingObject(), pConnStrings[i]) == m_createdDevices.End()) { nRetVal = TreesList.Add(Description, pConnStrings[i], NULL); if (nRetVal != XN_STATUS_OK) { xnOSFree(pConnStrings); return (nRetVal); } } } xnOSFree(pConnStrings); return (XN_STATUS_OK); }
XN_DDK_API XnStatus XnStreamDataSetCreate(XnStreamDataSet** ppStreamOutputSet) { XN_VALIDATE_OUTPUT_PTR(ppStreamOutputSet); // allocate struct XN_VALIDATE_CALLOC(*ppStreamOutputSet, XnStreamDataSet, 1); XnStreamDataSet* pSet = (*ppStreamOutputSet); // allocate hash table pSet->pHash = XN_NEW(XnStreamDataHash); if (pSet->pHash == NULL) { XnStreamDataSetDestroy(ppStreamOutputSet); return XN_STATUS_ALLOC_FAILED; } return XN_STATUS_OK; }
XnStatus XnExportedSensorDevice::EnumerateProductionTrees(xn::Context& context, xn::NodeInfoList& TreesList, xn::EnumerationErrors* pErrors) { XnStatus nRetVal = XN_STATUS_OK; // enumerate connected sensors XnUInt32 nCount = 0; // check if sensor is connected nRetVal = XnSensor::Enumerate(NULL, &nCount); if (nRetVal != XN_STATUS_OUTPUT_BUFFER_OVERFLOW) { // no sensor connected XN_LOG_WARNING_RETURN(XN_STATUS_DEVICE_NOT_CONNECTED, XN_MASK_DEVICE_SENSOR, "No PS sensor is connected!"); } // allocate according to count XnConnectionString* pConnStrings; XN_VALIDATE_CALLOC(pConnStrings, XnConnectionString, nCount); nRetVal = XnSensor::Enumerate(pConnStrings, &nCount); if (nRetVal != XN_STATUS_OK) { xnOSFree(pConnStrings); return (nRetVal); } XnProductionNodeDescription Description; GetDescription(&Description); // each connection string is a sensor. return it for (XnUInt32 i = 0; i < nCount; ++i) { nRetVal = TreesList.Add(Description, pConnStrings[i], NULL); if (nRetVal != XN_STATUS_OK) { xnOSFree(pConnStrings); return (nRetVal); } } xnOSFree(pConnStrings); return (XN_STATUS_OK); }
//--------------------------------------------------------------------------- // Code //--------------------------------------------------------------------------- XnStatus xnFPSInit(XnFPSData* pFPS, XnUInt32 nSamplesCount) { XN_VALIDATE_OUTPUT_PTR(pFPS); // make sure xnOS is init XnStatus nRetVal = xnOSInit(); if (nRetVal != XN_STATUS_OK && nRetVal != XN_STATUS_OS_ALREADY_INIT) return nRetVal; // Allocate struct XN_VALIDATE_CALLOC(*pFPS, XnFPSDataImpl, 1); XnFPSDataImpl* pData = *pFPS; // Allocate array XN_VALIDATE_ALIGNED_CALLOC(pData->anTimes, XnUInt64, nSamplesCount, XN_DEFAULT_MEM_ALIGN); pData->nArraySize = nSamplesCount; return XN_STATUS_OK; }
XN_C_API XnStatus xnEnumerationErrorsAdd(XnEnumerationErrors* pError, const XnProductionNodeDescription* pDesc, XnStatus nError) { XN_VALIDATE_INPUT_PTR(pError); XN_VALIDATE_INPUT_PTR(pDesc); // find where to add it XnModuleError** ppWhere = &pError->pFirst; while ((*ppWhere) != NULL) { ppWhere = &(*ppWhere)->pNext; } // allocate XnModuleError* pModuleError = NULL; XN_VALIDATE_CALLOC(pModuleError, XnModuleError, 1); pModuleError->description = *pDesc; pModuleError->nError = nError; *ppWhere = pModuleError; return (XN_STATUS_OK); }
XnStatus XnSensorFirmwareParams::CommitTransactionAsBatch() { XnStatus nRetVal = XN_STATUS_OK; if (!m_bInTransaction) { return XN_STATUS_ERROR; } // we are no longer in transaction, even if we fail to commit. m_bInTransaction = FALSE; if (m_TransactionOrder.Size() != 0) { XnUInt32 nMaxCount = m_TransactionOrder.Size(); XnInnerParamData* pParams; XN_VALIDATE_CALLOC(pParams, XnInnerParamData, nMaxCount); XnChar strLogMessage[1024]; XnUInt32 nMaxLength = 1024; XnUInt32 nLength = 0; XnUInt32 nChars; xnOSStrFormat(strLogMessage + nLength, nMaxLength - nLength, &nChars, "Setting firmware params:\n\t"); nLength += nChars; XnUInt32 nCount = 0; for (XnActualIntPropertyList::Iterator it = m_TransactionOrder.begin(); it != m_TransactionOrder.end(); ++it) { XnActualIntProperty* pProp = *it; XnUInt32 nValue; nRetVal = m_Transaction.Get(pProp, nValue); if (nRetVal != XN_STATUS_OK) { xnOSFree(pParams); return (nRetVal); } XnFirmwareParam* pParam; nRetVal = CheckFirmwareParam(pProp, nValue, &pParam); if (nRetVal != XN_STATUS_OK) { xnOSFree(pParams); return (nRetVal); } if (pParam != NULL) { xnOSStrFormat(strLogMessage + nLength, nMaxLength - nLength, &nChars, "%s = %u\n\t", pProp->GetName(), nValue); nLength += nChars; pParams[nCount].nParam = pParam->nFirmwareParam; pParams[nCount].nValue = (XnUInt16)nValue; nCount++; } } xnLogVerbose(XN_MASK_SENSOR_PROTOCOL, "%s", strLogMessage); // set all params nRetVal = m_pCommands->SetMultipleFirmwareParams(pParams, nCount); xnOSFree(pParams); XN_IS_STATUS_OK(nRetVal); // and update their props for (XnActualIntPropertyList::Iterator it = m_TransactionOrder.begin(); it != m_TransactionOrder.end(); ++it) { XnActualIntProperty* pProp = *it; XnUInt32 nValue; nRetVal = m_Transaction.Get(pProp, nValue); XN_IS_STATUS_OK(nRetVal); nRetVal = pProp->UnsafeUpdateValue(nValue); XN_IS_STATUS_OK(nRetVal); } } m_Transaction.Clear(); m_TransactionOrder.Clear(); return (XN_STATUS_OK); }
XnStatus XnFileDevice::BCInit() { XN_VALIDATE_CALLOC(m_pBCData, XnFileBCData, 1); return XN_STATUS_OK; }
XN_C_API XnStatus XN_C_DECL xnOSCreateSharedMemoryEx(const XnChar* strName, XnUInt32 nSize, XnUInt32 nAccessFlags, XnBool bAllowOtherUsers, XN_SHARED_MEMORY_HANDLE* phSharedMem) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_INPUT_PTR(strName); XN_VALIDATE_OUTPUT_PTR(phSharedMem); DWORD mapflags; nRetVal = AccessFlagsToWin32MapFlags(nAccessFlags, &mapflags); XN_IS_STATUS_OK(nRetVal); DWORD viewflags; nRetVal = AccessFlagsToWin32ViewFlags(nAccessFlags, &viewflags); XN_IS_STATUS_OK(nRetVal); XnChar strWinName[XN_FILE_MAX_PATH]; nRetVal = XnWin32CreateKernelObjectName(strWinName, MAX_PATH, strName, bAllowOtherUsers); if (nRetVal != XN_STATUS_OK) { return XN_STATUS_OS_EVENT_CREATION_FAILED; } SECURITY_ATTRIBUTES* pSecurityAttributes = NULL; nRetVal = XnWin32GetSecurityAttributes(bAllowOtherUsers, &pSecurityAttributes); if (nRetVal != XN_STATUS_OK) { return XN_STATUS_OS_EVENT_CREATION_FAILED; } // allocate handle XnOSSharedMemory* pHandle; XN_VALIDATE_CALLOC(pHandle, XnOSSharedMemory, 1); // create file mapping pHandle->hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // use paging file pSecurityAttributes, // security mapflags, // read/write access 0, // max. object size nSize, // buffer size strWinName); // name of mapping object if (pHandle->hMapFile == NULL) { XN_LOG_ERROR_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not create file mapping object (%d).", GetLastError()); } // map it to the process pHandle->pAddress = MapViewOfFile( pHandle->hMapFile, // handle to map object viewflags, // read/write permission 0, 0, nSize); if (pHandle->pAddress == NULL) { XN_LOG_ERROR_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not map view of file (%d).", GetLastError()); } *phSharedMem = pHandle; return (XN_STATUS_OK); }
static XnStatus OpenSharedMemoryImpl(const XnChar* strName, XnUInt32 nAccessFlags, XN_SHARED_MEMORY_HANDLE* phSharedMem, XnUInt32 nSize) { XnStatus nRetVal = XN_STATUS_OK; XN_VALIDATE_INPUT_PTR(strName); XN_VALIDATE_OUTPUT_PTR(phSharedMem); // if (nSize) is a number - create, otherwise - open XnBool bCreate = (nSize != 0); // convert to local OS types int prot = 0; int nCreateFlags = 0; int nMode = 0; nRetVal = AccessFlagsToMMapProt(nAccessFlags, &prot); XN_IS_STATUS_OK(nRetVal); nRetVal = AccessFlagsToOpenFlags(nAccessFlags, &nCreateFlags); XN_IS_STATUS_OK(nRetVal); // allocate handle XnOSSharedMemory* pHandle; XN_VALIDATE_CALLOC(pHandle, XnOSSharedMemory, 1); pHandle->bCreate = bCreate; NameToFileName(strName, pHandle->strFileName); if (bCreate) { nCreateFlags |= O_CREAT; nMode |= S_IRWXU | S_IRWXG | S_IRWXO; } // open file int fd = shm_open(pHandle->strFileName, nCreateFlags, nMode); if (fd == -1) { xnOSFree(pHandle); XN_LOG_WARNING_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not create file '%s' for shared memory (%d).", pHandle->strFileName, errno); } if (bCreate) { // set it to the right size if (-1 == ftruncate(fd, nSize)) { close(fd); shm_unlink(pHandle->strFileName); xnOSFree(pHandle); XN_LOG_WARNING_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not seek to position (%d).", pHandle->strFileName, errno); } pHandle->nSize = nSize; } else { // read shared object size pHandle->nSize = lseek(fd, 0, SEEK_END); } // and map it pHandle->pAddress = mmap(NULL, pHandle->nSize, prot, MAP_SHARED, fd, 0); if (pHandle->pAddress == MAP_FAILED) { close(fd); shm_unlink(pHandle->strFileName); xnOSFree(pHandle); XN_LOG_WARNING_RETURN(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, XN_MASK_OS, "Could not create file mapping object (%d).", errno); } close(fd); *phSharedMem = pHandle; return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBEnumerateDevices(XnUInt16 nVendorID, XnUInt16 nProductID, const XnUSBConnectionString** pastrDevicePaths, XnUInt32* pnCount) { // support up to 30 devices XnUSBConnectionString cpUSBID; XnUSBConnectionString cpUSBPathCmp; XnUSBConnectionString aNames[MAX_POTENTIAL_DEVICES]; HDEVINFO hDevInfo = NULL; ULONG nDevices = 0; XnUInt32 nFoundDevices = 0; SP_DEVICE_INTERFACE_DATA devInterfaceData; XnBool bReachedEnd = FALSE; // Validate xnUSB XN_VALIDATE_USB_INIT(); LPCGUID pInterfaceGuid = &GUID_CLASS_PSDRV_USB; // See if the driver is installed hDevInfo = SetupDiGetClassDevs (pInterfaceGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); if (hDevInfo == INVALID_HANDLE_VALUE) { // No devices are present... return (XN_STATUS_USB_DRIVER_NOT_FOUND); } // Scan the hardware for any devices that are attached to our driver. devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); while (nDevices < MAX_POTENTIAL_DEVICES) { // Get information about the device if (SetupDiEnumDeviceInterfaces(hDevInfo, 0, pInterfaceGuid, nDevices, &devInterfaceData)) { PSP_DEVICE_INTERFACE_DETAIL_DATA pDevInterfaceDetailData = NULL; ULONG nPredictedLength = 0; ULONG nRequiredLength = 0; // Probe how much memory is needed to read the device info SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData, NULL, 0, &nRequiredLength, NULL); // Allocate memory for the device info nPredictedLength = nRequiredLength; pDevInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(nPredictedLength); if(pDevInterfaceDetailData == NULL) { // Not enough memory... return XN_STATUS_ALLOC_FAILED; } // Read the device info pDevInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData, pDevInterfaceDetailData, nPredictedLength, &nRequiredLength, NULL)) { // Something bad has happened... free(pDevInterfaceDetailData); return XN_STATUS_ERROR; } // Make sure we have the right VID/PID cpUSBID[0] = 0; sprintf_s (cpUSBID, "vid_%04x&pid_%04x", nVendorID, nProductID); cpUSBPathCmp[0] = 0; StringCchCopy(cpUSBPathCmp, MAX_DEVICE_STR_LENGTH, pDevInterfaceDetailData->DevicePath); if (strstr(_strlwr(cpUSBPathCmp), cpUSBID) != 0) { StringCchCopy(aNames[nFoundDevices], MAX_DEVICE_STR_LENGTH, pDevInterfaceDetailData->DevicePath); ++nFoundDevices; } ++nDevices; } else if (ERROR_NO_MORE_ITEMS == GetLastError()) { // no more devices bReachedEnd = TRUE; break; } } SetupDiDestroyDeviceInfoList(hDevInfo); if (!bReachedEnd) { // we probably passed our limit XN_LOG_ERROR_RETURN(XN_STATUS_ERROR, XN_MASK_USB, "Found more than %d devices! This is not supported.", MAX_POTENTIAL_DEVICES); } XnUSBConnectionString* pNames; XN_VALIDATE_CALLOC(pNames, XnUSBConnectionString, nFoundDevices); xnOSMemCopy(pNames, aNames, sizeof(XnUSBConnectionString) * nFoundDevices); *pastrDevicePaths = pNames; *pnCount = nFoundDevices; // All is good... return (XN_STATUS_OK); }