BOOL MonitorEnumKeyChange(HANDLE hKeyChangeEvent, HANDLE hStopEvent) { LONG lResult; HKEY hEnumKey; BOOL fSuccess; lResult = ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, REGSTR_PATH_SYSTEMENUM, 0, KEY_NOTIFY, &hEnumKey); if (ERROR_SUCCESS != lResult) { DebugPrintErr(lResult, _T("RegOpenKeyEx(%s) failed"), REGSTR_PATH_SYSTEMENUM); return FALSE; } fSuccess = ::ResetEvent(hKeyChangeEvent); _ASSERTE(fSuccess); // Only we monitors the add or delete of ENUM's subkey only. lResult = ::RegNotifyChangeKeyValue( hEnumKey, FALSE, REG_NOTIFY_CHANGE_NAME, hKeyChangeEvent, TRUE); if (ERROR_SUCCESS != lResult) { DebugPrintErr(lResult, _T("RegNotifyChangeKeyValue(%s) failed"), REGSTR_PATH_SYSTEMENUM); ::RegCloseKey(hEnumKey); return FALSE; } DebugPrint(1, _T("Waiting for changes in %s.\n"), REGSTR_PATH_SYSTEMENUM); HANDLE hWaitingEvents[] = { hStopEvent, hKeyChangeEvent }; DWORD dwWaitResult = ::WaitForMultipleObjects( RTL_NUMBER_OF(hWaitingEvents), hWaitingEvents, FALSE, INFINITE); if (WAIT_OBJECT_0 != dwWaitResult && WAIT_OBJECT_0 + 1 != dwWaitResult) { DebugPrintErrEx(_T("Wait failed!")); ::RegCloseKey(hEnumKey); return FALSE; } DebugPrint(1, _T("Changes in %s notified.\n"), REGSTR_PATH_SYSTEMENUM); ::RegCloseKey(hEnumKey); return TRUE; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlGetVersion( LPWORD lpVersionMajor, LPWORD lpVersionMinor, LPWORD lpVersionBuild, LPWORD lpVersionPrivate) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; NDASBUS_GET_VERSION VersionData = {0}; hDevice = OpenBusInterface(); if(INVALID_HANDLE_VALUE == hDevice) { return FALSE; } fSuccess = DeviceIoControl ( hDevice, IOCTL_NDASBUS_GETVERSION, NULL, 0, &VersionData, sizeof(VersionData), &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("NdasBusCtlGetVersion failed :")); } else { if (NULL != lpVersionMajor) *lpVersionMajor = VersionData.VersionMajor; if (NULL != lpVersionMinor) *lpVersionMinor = VersionData.VersionMinor; if (NULL != lpVersionBuild) *lpVersionBuild = VersionData.VersionBuild; if (NULL != lpVersionPrivate) *lpVersionPrivate = VersionData.VersionPrivate; DebugPrint(3, _T("NdasBusCtlGetVersion %d.%d.%d.%d completed successfully.\n"), VersionData.VersionMajor, VersionData.VersionMinor, VersionData.VersionBuild, VersionData.VersionPrivate); } err = GetLastError(); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlQueryNodeAlive( DWORD SlotNo, LPBOOL pbAlive, LPBOOL pbAdapterHasError) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; NDASBUS_NODE_ALIVE_IN nodeAliveIn; NDASBUS_NODE_ALIVE_OUT nodeAliveOut; hDevice = OpenBusInterface(); if (INVALID_HANDLE_VALUE == hDevice) { return FALSE; } nodeAliveIn.SlotNo = SlotNo; fSuccess = DeviceIoControl( hDevice, IOCTL_NDASBUS_QUERY_NODE_ALIVE, &nodeAliveIn, sizeof(NDASBUS_NODE_ALIVE_IN), &nodeAliveOut, sizeof(NDASBUS_NODE_ALIVE_OUT), &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("NdasBusCtlQueryNodeAlive: BUSENUM_QUERY_NODE_ALIVE failed: ")); } else { *pbAlive = nodeAliveOut.bAlive; *pbAdapterHasError = nodeAliveOut.bHasError; } err = GetLastError(); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlQueryDvdStatus( DWORD SlotNo, PULONG pDvdStatus) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; NDASBUS_DVD_STATUS DvdStatusIn; NDASBUS_DVD_STATUS DvdStatusOut; hDevice = OpenBusInterface(); if (INVALID_HANDLE_VALUE == hDevice) { return FALSE; } DvdStatusIn.SlotNo = SlotNo; DvdStatusIn.Size = sizeof(NDASBUS_DVD_STATUS); fSuccess = DeviceIoControl( hDevice, IOCTL_NDASBUS_DVD_GET_STATUS, &DvdStatusIn, sizeof(NDASBUS_DVD_STATUS), &DvdStatusOut, sizeof(NDASBUS_DVD_STATUS), &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("NdasBusCtlQueryDvdStatus: BUSENUM_QUERY_NODE_ALIVE failed: ")); } else { DebugPrint(3, _T("NdasBusCtlQueryDvdStatus: Slot %d, Status %d\n"), SlotNo, DvdStatusOut.Status); *pDvdStatus = DvdStatusOut.Status; } err = GetLastError(); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlRemoveTarget(DWORD SlotNo) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; NDASBUS_REMOVE_TARGET_DATA RemoveTargetData; DebugPrint(3, _T("NdasBusCtlRemoveTarget: Slot %d\n"), SlotNo); hDevice = OpenBusInterface(); if(INVALID_HANDLE_VALUE == hDevice) { return FALSE; } ZeroMemory(&RemoveTargetData, sizeof(RemoveTargetData)); RemoveTargetData.ulSlotNo = SlotNo; // RemoveTargetData->MasterUnitDisk; fSuccess = DeviceIoControl( hDevice, IOCTL_NDASBUS_REMOVE_TARGET, &RemoveTargetData, sizeof(NDASBUS_REMOVE_TARGET_DATA), &RemoveTargetData, sizeof(NDASBUS_REMOVE_TARGET_DATA), &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("LanscsiRemoveTarget at slot %d failed: "), SlotNo); } else { DebugPrint(3, _T("LanscsiRemoveTarget at slot %d completed successfully.\n"), SlotNo); } err = GetLastError(); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlUnplug( ULONG SlotNo) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; NDASBUS_UNPLUG_HARDWARE unplug; DebugPrint(3, _T("NdasBusCtlUnplug at slot %d.\n"), SlotNo); hDevice = OpenBusInterface(); if(INVALID_HANDLE_VALUE == hDevice) { return FALSE; } ZeroMemory(&unplug, sizeof(NDASBUS_UNPLUG_HARDWARE)); unplug.SerialNo = SlotNo; unplug.Size = sizeof (unplug); fSuccess = DeviceIoControl ( hDevice, IOCTL_NDASBUS_UNPLUG_HARDWARE, &unplug, sizeof (unplug), &unplug, sizeof (unplug), &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("NdasBusCtlUnplug at slot %d failed :"), SlotNo); } else { DebugPrint(3, _T("NdasBusCtlUnplug at slot %d completed successfully.\n"), SlotNo); } err = GetLastError(); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
LSBUSCTLAPI BOOL WINAPI LsBusCtlEject( ULONG SlotNo) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; BUSENUM_EJECT_HARDWARE eject; DebugPrint(3, _T("LsBusCtlEject at slot %d.\n"), SlotNo); hDevice = OpenBusInterface(); if(INVALID_HANDLE_VALUE == hDevice) { return FALSE; } ZeroMemory(&eject, sizeof(BUSENUM_EJECT_HARDWARE)); eject.SlotNo = SlotNo; eject.Size = sizeof (eject); fSuccess = DeviceIoControl ( hDevice, IOCTL_BUSENUM_EJECT_HARDWARE, &eject, sizeof (eject), &eject, sizeof (eject), &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("LsBusCtlEject at slot %d failed :"), SlotNo); } else { DebugPrint(3, _T("LsBusCtlEject at slot %d completed successfully.\n"), SlotNo); } err = GetLastError(); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlStartStopRegistrarEnum( BOOL bOnOff, LPBOOL pbPrevState) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; DWORD onOff; hDevice = OpenBusInterface(); if (INVALID_HANDLE_VALUE == hDevice) { return FALSE; } onOff = bOnOff; fSuccess = DeviceIoControl( hDevice, IOCTL_NDASBUS_STARTSTOP_REGISTRARENUM, &onOff, sizeof(DWORD), &onOff, sizeof(DWORD), &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("LsBusCtlOnOffRegistrar: STOP_REGISTRAR failed: ")); } else { if(pbPrevState) *pbPrevState = (onOff != 0); } err = GetLastError(); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlUnregisterDevice( ULONG SlotNo) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; NDASBUS_UNREGISTER_NDASDEV unregisterDev; DebugPrint(3, _T("NdasBusCtlUnplug at slot %d.\n"), SlotNo); hDevice = OpenBusInterface(); if(INVALID_HANDLE_VALUE == hDevice) { return FALSE; } ZeroMemory(&unregisterDev, sizeof(NDASBUS_UNREGISTER_NDASDEV)); unregisterDev.SlotNo = SlotNo; fSuccess = DeviceIoControl ( hDevice, IOCTL_NDASBUS_UNREGISTER_DEVICE, &unregisterDev, sizeof (unregisterDev), &unregisterDev, sizeof (unregisterDev), &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("NdasBusCtlUnregisterDevice at slot %d failed :"), SlotNo); } else { DebugPrint(3, _T("NdasBusCtlUnregisterDevice at slot %d completed successfully.\n"), SlotNo); } err = GetLastError(); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlAddTarget( PNDASBUS_ADD_TARGET_DATA AddTargetData) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; DebugPrint(1, _T("NdasBusCtlAddTarget: Slot %d.\n"), AddTargetData->ulSlotNo); // Sleep(1000*5); hDevice = OpenBusInterface(); if(INVALID_HANDLE_VALUE == hDevice) { return FALSE; } fSuccess = DeviceIoControl( hDevice, IOCTL_NDASBUS_ADD_TARGET, AddTargetData, AddTargetData->ulSize, AddTargetData, AddTargetData->ulSize, &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("NdasBusCtlAddTarget at slot %d failed :"), AddTargetData->ulSlotNo); } else { DebugPrint(3, _T("NdasBusCtlAddTarget at slot %d completed successfully.\n"), AddTargetData->ulSlotNo); } err = GetLastError(); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlRegisterDevice( ULONG SlotNo, ULONG MaxOsDataTransferLength ) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; PNDASBUS_PLUGIN_HARDWARE_EX2 registerDev; DWORD cbRegisterDev = 0; DebugPrint(1, _T("NdasBusCtlRegisterDevice: Slot %d, MaxRequestBlock %d\n"), SlotNo, MaxOsDataTransferLength); hDevice = OpenBusInterface(); if(INVALID_HANDLE_VALUE == hDevice) { return FALSE; } cbReturned = sizeof (NDASBUS_PLUGIN_HARDWARE_EX2) + NDASMINIPORT_HARDWARE_IDS_W_SIZE; registerDev = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, cbReturned); // // The size field should be set to the sizeof the struct as declared // and *not* the size of the struct plus the multi_sz // registerDev->Size = sizeof(NDASBUS_PLUGIN_HARDWARE_EX2); registerDev->SerialNo = SlotNo; registerDev->MaxOsDataTransferLength = MaxOsDataTransferLength; registerDev->HardwareIDLen = NDASMINIPORT_HARDWARE_IDS_W_SIZE / sizeof(WCHAR); CopyMemory( registerDev->HardwareIDs, NDASMINIPORT_HARDWARE_IDS_W, NDASMINIPORT_HARDWARE_IDS_W_SIZE); fSuccess = DeviceIoControl ( hDevice, IOCTL_NDASBUS_REGISTER_DEVICE, registerDev, cbReturned, registerDev, cbReturned, &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("NdasBusCtlRegisterDevice at slot %d failed: "), SlotNo); } else { DebugPrintErrEx(_T("NdasBusCtlRegisterDevice at slot %d completed successfully.\n"), SlotNo); } err = GetLastError(); HeapFree(GetProcessHeap(), 0, registerDev); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
NDASBUSCTLAPI BOOL WINAPI NdasBusCtlPlugInEx2 ( ULONG SlotNo, ULONG MaxOsDataTransferLength, // in bytes PNDASBUS_ADD_TARGET_DATA NdasBusAddTargetData, HANDLE hEvent, HANDLE hAlarmEvent, BOOL NotRegister ) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; PNDASBUS_PLUGIN_HARDWARE_EX2 pLanscsiPluginData; DWORD cbLanscsiPluginData = 0; DebugPrint(1, _T("NdasBusCtlPlugInEx2: Slot %d, MaxRequestLength %d bytes, hEvent %p, hAlarmEvent %p\n"), SlotNo, MaxOsDataTransferLength, hEvent, hAlarmEvent); hDevice = OpenBusInterface(); if(INVALID_HANDLE_VALUE == hDevice) { return FALSE; } cbLanscsiPluginData = sizeof (NDASBUS_PLUGIN_HARDWARE_EX2) + NDASMINIPORT_HARDWARE_IDS_W_SIZE; pLanscsiPluginData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, cbLanscsiPluginData); // // The size field should be set to the sizeof the struct as declared // and *not* the size of the struct plus the multi_sz // pLanscsiPluginData->Size = sizeof(NDASBUS_PLUGIN_HARDWARE_EX2); pLanscsiPluginData->SerialNo = SlotNo; pLanscsiPluginData->MaxOsDataTransferLength = MaxOsDataTransferLength; pLanscsiPluginData->DisconEvent = hEvent; pLanscsiPluginData->AlarmEvent = hAlarmEvent; pLanscsiPluginData->HardwareIDLen = NDASMINIPORT_HARDWARE_IDS_W_SIZE / sizeof(WCHAR); CopyMemory( pLanscsiPluginData->HardwareIDs, NDASMINIPORT_HARDWARE_IDS_W, NDASMINIPORT_HARDWARE_IDS_W_SIZE); if(NotRegister) { pLanscsiPluginData->Flags |= PLUGINFLAG_NOT_REGISTER; } RtlCopyMemory( &pLanscsiPluginData->NdasBusAddTargetData, NdasBusAddTargetData, NdasBusAddTargetData->ulSize ); fSuccess = DeviceIoControl ( hDevice, IOCTL_NDASBUS_PLUGIN_HARDWARE_EX2, pLanscsiPluginData, cbLanscsiPluginData, pLanscsiPluginData, cbLanscsiPluginData, &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("NdasBusCtlPlugInEx2 at slot %d failed: "), SlotNo); } else { DebugPrintErrEx(_T("NdasBusCtlPlugInEx2 at slot %d completed successfully.\n"), SlotNo); } err = GetLastError(); HeapFree(GetProcessHeap(), 0, pLanscsiPluginData); CloseHandle(hDevice); SetLastError(err); return fSuccess; }
// // If succeeded, returns the device file of the LANSCSI Bus Enumerator // If failed, return INVALID_HANDLE_VALUE // static HANDLE OpenBusInterface(VOID) { BOOL fSuccess = FALSE; DWORD err = ERROR_SUCCESS; HANDLE hDevice = INVALID_HANDLE_VALUE; HDEVINFO hDevInfoSet = INVALID_HANDLE_VALUE; SP_INTERFACE_DEVICE_DATA devIntfData = {0}; PSP_INTERFACE_DEVICE_DETAIL_DATA devIntfDetailData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0; hDevInfoSet = SetupDiGetClassDevs ( (LPGUID)&GUID_NDAS_BUS_ENUMERATOR_INTERFACE_CLASS, NULL, // Define no enumerator (global) NULL, // Define no (DIGCF_PRESENT | // Only Devices present DIGCF_INTERFACEDEVICE)); // Function class devices. if (INVALID_HANDLE_VALUE == hDevInfoSet) { DebugPrintErrEx(_T("OpenBusInterface: SetupDiGetClassDevs failed: ")); goto cleanup; } devIntfData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); fSuccess = SetupDiEnumDeviceInterfaces ( hDevInfoSet, 0, // No care about specific PDOs (LPGUID)&GUID_NDAS_BUS_ENUMERATOR_INTERFACE_CLASS, 0, // &devIntfData); if (!fSuccess) { DebugPrintErrEx(_T("OpenBusInterface: SetupDiEnumDeviceInterfaces failed: ")); if (ERROR_NO_MORE_ITEMS == GetLastError()) { DebugPrint(1, _T("OpenBusInterface: Interface") _T(" GUID_NDAS_BUS_ENUMERATOR_INTERFACE_CLASS is not registered.\n")); } goto cleanup; } fSuccess = SetupDiGetInterfaceDeviceDetail ( hDevInfoSet, &devIntfData, NULL, // probing so no output buffer yet 0, // probing so output buffer length of zero &requiredLength, NULL // not interested in the specific dev-node ); if (!fSuccess && ERROR_INSUFFICIENT_BUFFER != GetLastError()) { DebugPrintErrEx(_T("OpenBusInterface: SetupDiGetInterfaceDeviceDetail failed: ")); goto cleanup; } predictedLength = requiredLength; devIntfDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, predictedLength); devIntfDetailData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA); fSuccess = SetupDiGetInterfaceDeviceDetail( hDevInfoSet, &devIntfData, devIntfDetailData, predictedLength, &requiredLength, NULL); if (!fSuccess) { DebugPrintErrEx(_T("OpenBusInterface: SetupDiGetInterfaceDeviceDetail failed: ")); goto cleanup; } DebugPrint(3, _T("OpenBusInterface: Opening %s\n"), devIntfDetailData->DevicePath); hDevice = CreateFile ( devIntfDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, // FILE_SHARE_READ | FILE_SHARE_WRITE NULL, // no SECURITY_ATTRIBUTES structure OPEN_EXISTING, // No special create flags 0, // No special attributes NULL); // No template file if (INVALID_HANDLE_VALUE == hDevice) { DebugPrintErrEx(_T("OpenBusInterface: Device not ready: ")); goto cleanup; } DebugPrint(3, _T("OpenBusInterface: Device file %s opened successfully.\n"), devIntfDetailData->DevicePath); cleanup: err = GetLastError(); if (INVALID_HANDLE_VALUE != hDevInfoSet) { SetupDiDestroyDeviceInfoList(hDevInfoSet); } if (NULL != devIntfDetailData) { HeapFree(GetProcessHeap(), 0, devIntfDetailData); } SetLastError(err); return hDevice; }
LSBUSCTLAPI BOOL WINAPI LsBusCtlPlugInEx2( ULONG SlotNo, ULONG MaxRequestBlocks, HANDLE hEvent, HANDLE hAlarmEvent, BOOL NotRegister ) { BOOL fSuccess = FALSE; HANDLE hDevice = INVALID_HANDLE_VALUE; DWORD cbReturned = 0; DWORD err; PBUSENUM_PLUGIN_HARDWARE_EX2 pLanscsiPluginData; DWORD cbLanscsiPluginData = 0; DebugPrint(1, _T("LsBusCtlPlugInEx2: Slot %d, MaxRequestBlock %d, hEvent %p, hAlarmEvent %p\n"), SlotNo, MaxRequestBlocks, hEvent, hAlarmEvent); hDevice = OpenBusInterface(); if(INVALID_HANDLE_VALUE == hDevice) { return FALSE; } cbLanscsiPluginData = sizeof (BUSENUM_PLUGIN_HARDWARE_EX2) + LSMINIPORT_HARDWARE_IDS_W_SIZE; pLanscsiPluginData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, cbLanscsiPluginData); // // The size field should be set to the sizeof the struct as declared // and *not* the size of the struct plus the multi_sz // pLanscsiPluginData->Size = sizeof(BUSENUM_PLUGIN_HARDWARE_EX2); pLanscsiPluginData->SlotNo = SlotNo; pLanscsiPluginData->MaxRequestBlocks = MaxRequestBlocks; pLanscsiPluginData->phEvent = &hEvent; pLanscsiPluginData->phAlarmEvent = &hAlarmEvent; pLanscsiPluginData->HardwareIDLen = LSMINIPORT_HARDWARE_IDS_W_SIZE / sizeof(WCHAR); CopyMemory( pLanscsiPluginData->HardwareIDs, LSMINIPORT_HARDWARE_IDS_W, LSMINIPORT_HARDWARE_IDS_W_SIZE); if(NotRegister) { pLanscsiPluginData->Flags |= PLUGINFLAG_NOT_REGISTER; } fSuccess = DeviceIoControl ( hDevice, IOCTL_BUSENUM_PLUGIN_HARDWARE_EX2, pLanscsiPluginData, cbLanscsiPluginData, pLanscsiPluginData, cbLanscsiPluginData, &cbReturned, NULL); if (!fSuccess) { DebugPrintErrEx(_T("LsBusCtlPlugInEx2 at slot %d failed: "), SlotNo); } else { DebugPrintErrEx(_T("LsBusCtlPlugInEx2 at slot %d completed successfully.\n"), SlotNo); } err = GetLastError(); HeapFree(GetProcessHeap(), 0, pLanscsiPluginData); CloseHandle(hDevice); SetLastError(err); return fSuccess; }