///////////////////////////////////////////////////////////////////////// // // CMyDevice::OnD0Exit // // This method is called when a device leaves the system // // Parameters: // pWdfDevice - pointer to a device object // // // ///////////////////////////////////////////////////////////////////////// HRESULT CMyDevice::OnD0Exit( _In_ IWDFDevice* pWdfDevice, _In_ WDF_POWER_DEVICE_STATE newState ) { Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry"); UNREFERENCED_PARAMETER(pWdfDevice); UNREFERENCED_PARAMETER(newState); HRESULT hr = S_OK; hr = EnterProcessing(PROCESSING_IPNPCALLBACK); if (SUCCEEDED(hr)) { if( SUCCEEDED(hr) && NULL != m_pSensorManager) { hr = m_pSensorManager->Stop(newState); } } // processing in progress ExitProcessing(PROCESSING_IPNPCALLBACK); Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Exit, hr = %!HRESULT!", hr); return hr; }
//modify by QP on 2k8-4-7 //add two parameters //int dis; int cri; for distance function and criteria function seperately TRAININGSET CheckParameters(char *TSName, char *CBName, char *PAName, char *InName, int Minclus,int Maxclus, int ow) { TRAININGSET TS; /* input training set doesn't exist */ if (!ExistFile(TSName)) { ErrorMessage("\nERROR: Input training set doesn't exist: " "%s\n\n", TSName); ExitProcessing(FATAL_ERROR); } /* result codebook file exists and we are told not to overwrite */ if (ExistFile(CBName) && !ow) { ErrorMessage("\nERROR: Result codebook already exists: " "%s\n\n", CBName); ExitProcessing(FATAL_ERROR); } /* result partitioning file exists and we are told not to overwrite */ if (*PAName && ExistFile(PAName) && !ow) { ErrorMessage("\nERROR: Result partitioning already exists: " "%s\n\n", PAName); ExitProcessing(FATAL_ERROR); } /* initial codebook / partitioning doesn't exist */ if (*InName && !DetermineFileName(InName)) { ErrorMessage("\nERROR: Initial codebook/partitioning doesn't exist: %s\n\n", InName); ExitProcessing(FATAL_ERROR); } //add by QP on 2k8-4-7 //verify whether Max is bigger than min; make sure the range is ok if (Maxclus < Minclus ) { ErrorMessage("Bad range: %i < %i.\n", Maxclus, Minclus); ExitProcessing(FATAL_ERROR); } ReadTrainingSet(TSName, &TS); //add by QP on 2k7-11-7 //the size of training set should be at least more than min codebook /* result codebook cannot contain more vectors than training set */ if (BookSize(&TS) < Minclus) { ErrorMessage("\nERROR: Number of vectors in training set "); ErrorMessage("(%d) < Min number of clusters ", BookSize(&TS)); ErrorMessage("(%d%d)!\n\n", Minclus, Maxclus); FreeCodebook(&TS); ExitProcessing(FATAL_ERROR); } return TS; } /* CheckParameters() */
char* KMeansInfo(void) { char* p; int len; len = strlen(ProgName)+strlen(VersionNumber)+strlen(LastUpdated)+4; p = (char*) malloc(len*sizeof(char)); if (!p) { ErrorMessage("ERROR: Allocating memory failed!\n"); ExitProcessing(FATAL_ERROR); } sprintf(p, "%s\t%s\t%s", ProgName, VersionNumber, LastUpdated); return p; } /* KMeansInfo() */
///////////////////////////////////////////////////////////////////////// // // CMyDevice::OnD0Entry // // This method is called after a new device enters the system // // Parameters: // pWdfDevice - pointer to a device object // // ///////////////////////////////////////////////////////////////////////// HRESULT CMyDevice::OnD0Entry( _In_ IWDFDevice* pWdfDevice, _In_ WDF_POWER_DEVICE_STATE previousState ) { Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry"); UNREFERENCED_PARAMETER(pWdfDevice); UNREFERENCED_PARAMETER(previousState); HRESULT hr = S_OK; hr = EnterProcessing(PROCESSING_IPNPCALLBACK); if (SUCCEEDED(hr) && (previousState == WdfPowerDeviceD3 || previousState == WdfPowerDeviceD3Final)) { if( NULL != m_pSensorManager && NULL != m_pSensorManager->m_pSensorDDI) { if (TRUE == m_pSensorManager->m_pSensorDDI->m_fDeviceIdle) { hr = m_pSensorManager->m_pSensorDDI->InitSensorDevice(m_pSensorManager->m_spWdfDevice); } if (!SUCCEEDED(hr)) { hr = E_UNEXPECTED; Trace(TRACE_LEVEL_ERROR, "Unable to re-initialize sensor device, hr = %!HRESULT!", hr); } else { m_pSensorManager->m_pSensorDDI->OnDeviceReconnect(); } } } // processing in progress ExitProcessing(PROCESSING_IPNPCALLBACK); Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Exit, hr = %!HRESULT!", hr); return hr; }
///////////////////////////////////////////////////////////////////////// // // CMyQueue::OnDeviceIoControl // // This method is called when an IOCTL is sent to the device // // Parameters: // pQueue - pointer to an IO queue // pRequest - pointer to an IO request // ControlCode - The IOCTL to process // InputBufferSizeInBytes - the size of the input buffer // OutputBufferSizeInBytes - the size of the output buffer // ///////////////////////////////////////////////////////////////////////// STDMETHODIMP_ (void) CMyQueue::OnDeviceIoControl( _In_ IWDFIoQueue* pQueue, _In_ IWDFIoRequest* pRequest, _In_ ULONG ControlCode, SIZE_T InputBufferSizeInBytes, SIZE_T OutputBufferSizeInBytes ) { UNREFERENCED_PARAMETER(pQueue); UNREFERENCED_PARAMETER(InputBufferSizeInBytes); UNREFERENCED_PARAMETER(OutputBufferSizeInBytes); //Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry"); DWORD dwWritten = 0; if( IS_WPD_IOCTL( ControlCode ) ) { if (FAILED(EnterProcessing(PROCESSING_IQUEUECALLBACKDEVICEIOCONTROL))) { // Unsupported request pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0); } else { m_pParentDevice->ProcessIoControl( pQueue, pRequest, ControlCode, InputBufferSizeInBytes, OutputBufferSizeInBytes, &dwWritten); } // processing in progress ExitProcessing(PROCESSING_IQUEUECALLBACKDEVICEIOCONTROL); } else { // Unsupported request pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0); } }
///////////////////////////////////////////////////////////////////////// // // CMyDevice::OnSelfManagedIoFlush // // Called by UMDF to flush the device for a device's self-managed // I/O operations. // // Parameters: // pWdfDevice - pointer to an IWDFDevice object representing the // device // // Return Values: // ///////////////////////////////////////////////////////////////////////// VOID CMyDevice::OnSelfManagedIoFlush( _In_ IWDFDevice* pWdfDevice ) { UNREFERENCED_PARAMETER(pWdfDevice); Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry"); HRESULT hr = EnterProcessing(PROCESSING_IPNPCALLBACKSELFMANAGEDIO); if (SUCCEEDED(hr)) { if (nullptr != m_spQueue) { Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Purging queue"); m_spQueue->PurgeSynchronously(); } } ExitProcessing(PROCESSING_IPNPCALLBACKSELFMANAGEDIO); Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Exit, hr = %!HRESULT!", hr); }
///////////////////////////////////////////////////////////////////////// // // CMyDevice::OnCleanupFile // // This method is called when the file handle to the device is closed // // Parameters: // pWdfFile - pointer to a file object // ///////////////////////////////////////////////////////////////////////// VOID CMyDevice::OnCleanupFile( _In_ IWDFFile* pWdfFile ) { //Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry"); HRESULT hr = S_OK; hr = EnterProcessing(PROCESSING_IFILECALLBACKCLEANUP); if (SUCCEEDED(hr)) { if (NULL != m_pSensorManager) { m_pSensorManager->CleanupFile(pWdfFile); } } // processing in progress ExitProcessing(PROCESSING_IFILECALLBACKCLEANUP); return; }
///////////////////////////////////////////////////////////////////////// // // CMyDevice::OnSelfManagedIoSuspend // // Called by UMDF to suspend a device's self-managed I/O operations. // // All outstanding I/O must be completed. The queue is stopped // to flush out in progress requests. The queue is restarted and // the driver continues to get I/O, but the m_fDeviceActive flag is // set to false so that the hardware will not be accessed. // // Parameters: // pWdfDevice - pointer to an IWDFDevice object representing the // device // // Return Values: // S_OK: success // ///////////////////////////////////////////////////////////////////////// HRESULT CMyDevice::OnSelfManagedIoSuspend( _In_ IWDFDevice* pWdfDevice ) { UNREFERENCED_PARAMETER(pWdfDevice); Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry"); HRESULT hr = EnterProcessing(PROCESSING_IPNPCALLBACKSELFMANAGEDIO); if (SUCCEEDED(hr)) { if (nullptr != m_pSensorManager) { Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Hardware is now not available"); m_pSensorManager->m_fDeviceActive = false; } if (nullptr != m_spQueue) { Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Flushing queue of running requests"); // TODO If all hardware requests are not guaranteed to complete within 1 second then // the queue should be stopped and all pending hardweare requests canceled //m_spQueue->Stop(nullptr); // Uncomment this line if the hardware requests need to be canceled // As noted above, cancel all pending hardware requests here to allow all ISensorDriver:: callbacks to complete m_spQueue->StopSynchronously(); // NOTE Any asynchronous work that accesses the hardware should be stopped m_spQueue->Start(); } } ExitProcessing(PROCESSING_IPNPCALLBACKSELFMANAGEDIO); Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Exit, hr = %!HRESULT!", hr); return hr; }
///////////////////////////////////////////////////////////////////////// // // CMyDevice::OnSelfManagedIoRestart // // Called by UMDF to restart a device's self-managed I/O operations. // // Parameters: // pWdfDevice - pointer to an IWDFDevice object representing the // device // // Return Values: // S_OK: success // ///////////////////////////////////////////////////////////////////////// HRESULT CMyDevice::OnSelfManagedIoRestart( _In_ IWDFDevice* pWdfDevice ) { UNREFERENCED_PARAMETER(pWdfDevice); Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry"); HRESULT hr = EnterProcessing(PROCESSING_IPNPCALLBACKSELFMANAGEDIO); if (SUCCEEDED(hr)) { if (nullptr != m_pSensorManager) { Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Hardware is now available"); m_pSensorManager->m_fDeviceActive = true; } } ExitProcessing(PROCESSING_IPNPCALLBACKSELFMANAGEDIO); Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Exit, hr = %!HRESULT!", hr); return hr; }
///////////////////////////////////////////////////////////////////////// // // CMyDevice::OnPrepareHardware // // Called by UMDF to prepare the hardware for use. In our case // we create the SensorDDI object and initialize the Sensor Class Extension // // Parameters: // pWdfDevice - pointer to an IWDFDevice object representing the // device // // Return Values: // S_OK: success // ///////////////////////////////////////////////////////////////////////// HRESULT CMyDevice::OnPrepareHardware( _In_ IWDFDevice* pWdfDevice ) { Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry"); HRESULT hr = (NULL != pWdfDevice) ? S_OK : E_UNEXPECTED; if (SUCCEEDED(hr)) { hr = EnterProcessing(PROCESSING_IPNPCALLBACKHARDWARE); if (SUCCEEDED(hr)) { if( NULL != pWdfDevice ) { // Store the IWDFDevice pointer m_spWdfDevice = pWdfDevice; } // Create & Configure the default IO Queue if (SUCCEEDED(hr)) { hr = ConfigureQueue(); } // Create the sensor manager object if (SUCCEEDED(hr)) { hr = CComObject<CSensorManager>::CreateInstance(&m_pSensorManager); if (nullptr != m_pSensorManager) { if ((SUCCEEDED(hr)) && (NULL != m_pSensorManager)) { m_pSensorManager->AddRef(); } // Initialize the sensor manager object if(SUCCEEDED(hr)) { hr = m_pSensorManager->Initialize(m_spWdfDevice, this); } } else { hr = E_POINTER; } } if (SUCCEEDED(hr)) { hr = StringCchCopy(m_pSensorManager->m_wszDeviceName, MAX_PATH, DEFAULT_DEVICE_MODEL_VALUE); if (SUCCEEDED(hr)) { ULONG ulCchInstanceId = 0; BOOL fResult = FALSE; WCHAR* wszInstanceId = nullptr; WCHAR* tempStr = nullptr; try { wszInstanceId = new WCHAR[MAX_PATH]; } catch(...) { hr = E_UNEXPECTED; Trace(TRACE_LEVEL_ERROR, "Failed to allocate memory for instance ID string, hr = %!HRESULT!", hr); if (nullptr != wszInstanceId) { delete[] wszInstanceId; } } try { tempStr = new WCHAR[MAX_PATH]; } catch(...) { hr = E_UNEXPECTED; Trace(TRACE_LEVEL_ERROR, "Failed to allocate memory for instance ID temp string, hr = %!HRESULT!", hr); if (nullptr != tempStr) { delete[] tempStr; } } if (SUCCEEDED(pWdfDevice->RetrieveDeviceInstanceId(NULL, &ulCchInstanceId))) { if (SUCCEEDED(pWdfDevice->RetrieveDeviceInstanceId(wszInstanceId, &ulCchInstanceId))) { HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; if (INVALID_HANDLE_VALUE != (hDeviceInfo = ::SetupDiCreateDeviceInfoList(NULL, NULL))) { SP_DEVINFO_DATA deviceInfo = {sizeof(SP_DEVINFO_DATA)}; if (TRUE == ::SetupDiOpenDeviceInfo(hDeviceInfo, wszInstanceId, NULL, 0, &deviceInfo)) { DEVPROPTYPE propType; ULONG ulSize; fResult = ::SetupDiGetDeviceProperty(hDeviceInfo, &deviceInfo, &DEVPKEY_Device_DeviceDesc, &propType, (PBYTE)tempStr, MAX_PATH*sizeof(WCHAR), &ulSize, 0); if (FALSE == fResult) { hr = HRESULT_FROM_WIN32(GetLastError()); } #pragma warning(suppress: 26035) //possible failure to null terminate string if (SUCCEEDED(hr) && (wcscmp(tempStr, L"") != 0)) { wcscpy_s(m_pSensorManager->m_wszDeviceName, MAX_PATH, tempStr); } ::SetupDiDestroyDeviceInfoList(hDeviceInfo); } } } } #pragma warning(suppress: 6001) //using unitialized memory if (nullptr != wszInstanceId) { delete[] wszInstanceId; } #pragma warning(suppress: 6001) //using unitialized memory if (nullptr != tempStr) { delete[] tempStr; } } } } // processing in progress ExitProcessing(PROCESSING_IPNPCALLBACKHARDWARE); } if (FAILED(hr)) { Trace(TRACE_LEVEL_CRITICAL, "Abnormal results during hardware initialization, hr = %!HRESULT!", hr); } Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Exit, hr = %!HRESULT!", hr); return hr; }
///////////////////////////////////////////////////////////////////////// // // CMyQueue::OnDeviceIoControl // // This method is called when an IOCTL is sent to the device // // Parameters: // pQueue - pointer to an IO queue // pRequest - pointer to an IO request // ControlCode - The IOCTL to process // InputBufferSizeInBytes - the size of the input buffer // OutputBufferSizeInBytes - the size of the output buffer // ///////////////////////////////////////////////////////////////////////// STDMETHODIMP_ (void) CMyQueue::OnDeviceIoControl( _In_ IWDFIoQueue* pQueue, _In_ IWDFIoRequest* pRequest, _In_ ULONG ControlCode, SIZE_T InputBufferSizeInBytes, SIZE_T OutputBufferSizeInBytes ) { UNREFERENCED_PARAMETER(pQueue); UNREFERENCED_PARAMETER(InputBufferSizeInBytes); UNREFERENCED_PARAMETER(OutputBufferSizeInBytes); //Trace(TRACE_LEVEL_INFORMATION, "%!FUNC! Entry"); DWORD dwWritten = 0; if (IOCTL_GPS_RADIO_MANAGEMENT_GET_RADIO_STATE == ControlCode || IOCTL_GPS_RADIO_MANAGEMENT_GET_PREVIOUS_RADIO_STATE == ControlCode || IOCTL_GPS_RADIO_MANAGEMENT_SET_RADIO_STATE == ControlCode || IOCTL_GPS_RADIO_MANAGEMENT_SET_PREVIOUS_RADIO_STATE == ControlCode ) { #if (NTDDI_VERSION >= NTDDI_WIN8) if (FAILED(EnterProcessing(PROCESSING_IQUEUECALLBACKDEVICEIOCONTROL))) { // Unsupported request pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0); } else { HRESULT hr = m_pParentDevice->ProcessIoControlRadioManagement(pRequest, ControlCode); pRequest->CompleteWithInformation(hr, sizeof(DEVICE_RADIO_STATE)); } // processing in progress ExitProcessing(PROCESSING_IQUEUECALLBACKDEVICEIOCONTROL); #endif } else if( IS_WPD_IOCTL( ControlCode ) ) { if (FAILED(EnterProcessing(PROCESSING_IQUEUECALLBACKDEVICEIOCONTROL))) { // Unsupported request pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0); } else { m_pParentDevice->ProcessIoControl( pQueue, pRequest, ControlCode, InputBufferSizeInBytes, OutputBufferSizeInBytes, &dwWritten); } // processing in progress ExitProcessing(PROCESSING_IQUEUECALLBACKDEVICEIOCONTROL); } else { // Unsupported request pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0); } }
//modify by QP on 2k8-4-7 //change the function ReadInitialCBorPA( ) //add two parameters int Minclus and Maxclus,delete int clus //Minclus -- Min number of clusters //Maxclus -- Max number of clusters int ReadInitialCBorPA(char *InName, int Minclus, int Maxclus, TRAININGSET *pTS, CODEBOOK *pCB, PARTITIONING *pP) { int useInitial = 0; if (*InName) /* we use initial codebook/partitioning */ { switch (DetermineCBFileType(InName)) { case TSFILE: case CBFILE: ReadCodebook(InName, pCB); useInitial = 1; //modify by QP on 2k8-4-7 //If we use initial ones, we just need to judge the size of codebook/ //training set is in the range: [Minclus, Maxclus] if (BookSize(pCB) < Minclus || BookSize(pCB) > Maxclus ) { ErrorMessage("\nERROR: Number of vectors in initial codebook "); ErrorMessage("(%d) <> number of clusters ", BookSize(pCB)); ErrorMessage("(%d)(%d)!\n\n", Minclus, Maxclus); FreeCodebook(pTS); FreeCodebook(pCB); ExitProcessing(FATAL_ERROR); } CreateNewPartitioning(pP, pTS, BookSize(pCB)); break; case PAFILE: ReadPartitioning(InName, pP, pTS); useInitial = 2; //modify by QP on 2k8-4-7 //judge the size of partitioning is in the range: [Minclus, Maxclus] if (PartitionCount(pP)<Minclus || PartitionCount(pP) > Maxclus) { ErrorMessage("\nERROR: Number of partitions in initial partitioning "); ErrorMessage("(%d) <> number of clusters ", PartitionCount(pP)); ErrorMessage("(%d)(%d)!\n\n", Minclus, Maxclus); FreeCodebook(pTS); FreePartitioning(pP); ExitProcessing(FATAL_ERROR); } CreateNewCodebook(pCB, PartitionCount(pP), pTS); break; case NOTFOUND: ErrorMessage("\nERROR: Type of initial codebook/partitioning file " "%s is unidentified!\n\n", InName); FreeCodebook(pTS); ExitProcessing(FATAL_ERROR); break; } } else /* we don't use initial codebook/partitioning */ { // CreateNewCodebook(pCB, clus, pTS); // CreateNewPartitioning(pP, pTS, clus); useInitial = 0; } return useInitial; }