HRESULT CNdasUnitImpl::ImplInitialize( __in INdasDevice* pNdasDevice, __in DWORD UnitNo, __in NDAS_UNITDEVICE_TYPE Type, __in NDAS_UNITDEVICE_SUBTYPE SubType, __in const NDAS_UNITDEVICE_HARDWARE_INFO& HardwareInfo, __in const NDAS_LOGICALUNIT_DEFINITION& NdasLogicalUnitDefinition, __in DWORD LuSequence) { m_pParentNdasDevice = pNdasDevice; m_unitDeviceId = pCreateUnitDeviceId(pNdasDevice,UnitNo); m_type = Type; m_subType = SubType; m_status = NDAS_UNITDEVICE_STATUS_NOT_MOUNTED; m_lastError = NDAS_UNITDEVICE_ERROR_NONE; m_udinfo = HardwareInfo; m_NdasLogicalUnitDefinition = NdasLogicalUnitDefinition; m_NdasLogicalUnitSequence = LuSequence; XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_INFORMATION, "NdasUnit=%p, %s\n", this, CNdasUnitDeviceId(m_unitDeviceId).ToStringA()); DWORD slotNo; COMVERIFY(pNdasDevice->get_SlotNo(&slotNo)); COMVERIFY( StringCchPrintf( m_szRegContainer, 30, _T("Devices\\%04d\\%04d"), slotNo, m_unitDeviceId.UnitNo)); return S_OK; }
DWORD CNdasAutoRegister::ThreadStart(HANDLE hStopEvent) { CCoInitialize coinit(COINIT_MULTITHREADED); XTLASSERT(!m_hSemQueue.IsInvalid() && "Don't forget to call initialize()."); // Queue Semaphore, Terminating Thread, Pipe Instances(MAX...) HANDLE hWaitHandles[2] = { hStopEvent, m_hSemQueue }; CNdasDeviceHeartbeatListener& listener = pGetNdasDeviceHeartbeatListener(); COMVERIFY(listener.Advise(this)); do { DWORD waitResult = ::WaitForMultipleObjects( RTL_NUMBER_OF(hWaitHandles), hWaitHandles, FALSE, INFINITE); if (WAIT_OBJECT_0 == waitResult) { break; } else if (WAIT_OBJECT_0 + 1 == waitResult) { while (TRUE) { m_queueLock.LockInstance(); if (m_queue.empty()) { m_queueLock.UnlockInstance(); break; } QUEUE_ENTRY entry = m_queue.front(); m_queue.pop(); m_queueLock.UnlockInstance(); (VOID) ProcessRegister(entry.deviceID, entry.access); } } else { XTLASSERT(FALSE); // ERROR } } while (TRUE); COMVERIFY(listener.Unadvise(this)); return 0; }
void CNdasEventMonitor::OnLogicalDeviceAlarmedByPnP( __in INdasLogicalUnit* pNdasLogicalUnit, __in ULONG NewAdapterStatus) { NDAS_LOCATION ndasLocation; COMVERIFY(pNdasLogicalUnit->get_Id(&ndasLocation)); XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Alarm Event, ndasLocation=%08X, logicalUnit=%p\n", ndasLocation, pNdasLogicalUnit); if (0 == ndasLocation) { XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR, "Invalid SCSI Location\n"); XTLASSERT(FALSE); return; } XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Logical device alarmed by PnP, ndasLocation=%08X, adapterStatus=%08X.\n", ndasLocation, NewAdapterStatus); // Determine whether an alarm will be issued. // Only viable alarm will be published ULONG currentAdapterStatus; COMVERIFY(pNdasLogicalUnit->get_AdapterStatus(¤tAdapterStatus)); if (pIsViableAlarmStatus(currentAdapterStatus, NewAdapterStatus)) { CNdasEventPublisher& epub = pGetNdasEventPublisher(); if (ADAPTERINFO_ISSTATUS(NewAdapterStatus, NDASSCSI_ADAPTER_STATUS_STOPPED) && ADAPTERINFO_ISSTATUSFLAG(NewAdapterStatus, NDAS_DEVICE_ALARM_STATUSFLAG_ABNORMAL_TERMINAT)) { // // Notify abnormal removal of the LU device. // OnLogicalDeviceDisconnected(pNdasLogicalUnit); } else { NDAS_LOGICALDEVICE_ID logicalUnitId; COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId)); (void) epub.LogicalDeviceAlarmed( logicalUnitId, pGetSignificantAlarm(currentAdapterStatus, NewAdapterStatus)); } } COMVERIFY(pNdasLogicalUnit->put_AdapterStatus(NewAdapterStatus)); }
STDMETHODIMP CNdasLogicalUnitManager::RegisterNdasLocation( NDAS_LOCATION location, INdasLogicalUnit* pNdasLogicalUnit) { CAutoLock autolock(this); NDAS_LOGICALDEVICE_ID logicalUnitId; COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId)); XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_INFORMATION, "RegisterNdasLocation, slot=%d, logDevice=%d\n", location, logicalUnitId); bool result = m_NdasLocationMap.insert( std::make_pair(location,pNdasLogicalUnit)).second; // // result can be false if RAID information is conflicting status // i.e. First RAID member is member of multiple RAID set. // // XTLASSERT(result); return result ? S_OK : E_FAIL; }
CNdasUnitDevice::CNdasUnitDevice( CNdasDevicePtr pParentDevice, DWORD dwUnitNo, NDAS_UNITDEVICE_TYPE type, NDAS_UNITDEVICE_SUBTYPE subType, const NDAS_UNITDEVICE_HARDWARE_INFO& unitDeviceInfo, const NDAS_LOGICALDEVICE_GROUP& ldGroup, DWORD ldSequence) : CStringizerA<32>("%s.%02d", pParentDevice->ToStringA(), dwUnitNo), m_pParentDevice(pParentDevice), m_unitDeviceId(pCreateUnitDeviceId(pParentDevice,dwUnitNo)), m_type(type), m_subType(subType), m_status(NDAS_UNITDEVICE_STATUS_NOT_MOUNTED), m_lastError(NDAS_UNITDEVICE_ERROR_NONE), m_udinfo(unitDeviceInfo), m_ldGroup(ldGroup), m_ldSequence(ldSequence), m_bSupposeFault(FALSE) { XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_INFORMATION, __FUNCTION__ " %s\n", ToStringA()); ::ZeroMemory( &m_PrimaryHostInfo, sizeof(NDAS_UNITDEVICE_PRIMARY_HOST_INFO)); COMVERIFY( StringCchPrintf( m_szRegContainer, 30, _T("Devices\\%04d\\%04d"), pParentDevice->GetSlotNo(), m_unitDeviceId.UnitNo)); }
STDMETHODIMP CNdasUnitImpl::RegisterToLogicalUnitManager() { HRESULT hr; CComPtr<INdasLogicalUnitManager> pManager; COMVERIFY(hr = pGetNdasLogicalUnitManager(&pManager)); CComPtr<INdasLogicalUnit> pNdasLogicalUnit; hr = pManager->Register(this, &pNdasLogicalUnit); if (FAILED(hr)) { XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR, "NdasLogicalUnitManager::Register failed, NdasUnit=%p, hr=0x%X\n", this, hr); return hr; } LockInstance(); m_pNdasLogicalUnit = pNdasLogicalUnit; UnlockInstance(); return S_OK; }
HRESULT CNdasDeviceComm::Connect(BOOL bWriteAccess) { if (m_hNdas) { ATLASSERT(FALSE); ATLVERIFY( Disconnect() ); } // Binding Address List SOCKADDR_LPX localSockAddrLpx; SOCKET_ADDRESS localSocketAddress; localSocketAddress.iSockaddrLength = sizeof(SOCKADDR_LPX); localSocketAddress.lpSockaddr = reinterpret_cast<LPSOCKADDR>(&localSockAddrLpx); COMVERIFY(m_pNdasDevice->get_LocalAddress(&localSocketAddress)); SOCKET_ADDRESS_LIST localAddressList; localAddressList.iAddressCount = 1; localAddressList.Address[0] = localSocketAddress; // Connection Information NDASCOMM_CONNECTION_INFO ci = {0}; ci.Size = sizeof(NDASCOMM_CONNECTION_INFO); ci.AddressType = NDASCOMM_CIT_DEVICE_ID; COMVERIFY(m_pNdasDevice->get_NdasDeviceId(&ci.Address.DeviceId)); ci.LoginType = NDASCOMM_LOGIN_TYPE_NORMAL; COMVERIFY(m_pNdasDevice->get_HardwarePassword(&ci.OEMCode.UI64Value)); ci.Protocol = NDASCOMM_TRANSPORT_LPX; ci.UnitNo = m_dwUnitNo; ci.WriteAccess = bWriteAccess; ci.BindingSocketAddressList = &localAddressList; m_hNdas = ::NdasCommConnect(&ci); if (NULL == m_hNdas) { HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); XTLTRACE2(NDASSVC_NDASCOMM, TRACE_LEVEL_ERROR, "NdasCommConnect failed, hr=0x%X\n", hr); return hr; } return S_OK; }
void CComponentObj::RegisterActiveObject() { ASSERT( registeractiveobjectret == 0 ); COMVERIFY( ::RegisterActiveObject(GetInterface(), CLSID_MgaComponent, ACTIVEOBJECT_STRONG, ®isteractiveobjectret) ); ASSERT( registeractiveobjectret ); }
bool operator()(INdasDevice* pNdasDevice) const { DWORD flags; COMVERIFY(pNdasDevice->get_RegisterFlags(&flags)); if (flags & NDAS_DEVICE_REG_FLAG_HIDDEN) { return true; } return false; }
void CNdasEventMonitor::OnLogicalDeviceDisconnected( INdasLogicalUnit* pNdasLogicalUnit) { NDAS_LOCATION location; COMVERIFY(pNdasLogicalUnit->get_Id(&location)); XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR, "Disconnect Event, ndasLocation=%d, logicalUnit=%p\n", location, pNdasLogicalUnit); NDAS_LOGICALDEVICE_ID logicalDeviceId; COMVERIFY(pNdasLogicalUnit->get_Id(&logicalDeviceId)); CNdasEventPublisher& epub = pGetNdasEventPublisher(); (void) epub.LogicalDeviceDisconnected(logicalDeviceId); CComQIPtr<INdasLogicalUnitPnpSink> pNdasLogicalUnitPnpSink(pNdasLogicalUnit); pNdasLogicalUnitPnpSink->OnDisconnected(); }
HRESULT CNdasUnitImpl::ConnectUnitDevice( HNDAS *ndasHandle) { // // Binding Address List // SOCKADDR_LPX localSockAddrLpx; SOCKET_ADDRESS localSocketAddress; localSocketAddress.iSockaddrLength = sizeof(SOCKADDR_LPX); localSocketAddress.lpSockaddr = reinterpret_cast<LPSOCKADDR>(&localSockAddrLpx); COMVERIFY(m_pParentNdasDevice->get_LocalAddress(&localSocketAddress)); SOCKET_ADDRESS_LIST localAddressList; localAddressList.iAddressCount = 1; localAddressList.Address[0] = localSocketAddress; // Connection Information NDASCOMM_CONNECTION_INFO ci = {0}; ci.Size = sizeof(NDASCOMM_CONNECTION_INFO); ci.AddressType = NDASCOMM_CIT_DEVICE_ID; COMVERIFY(m_pParentNdasDevice->get_NdasDeviceId(&ci.Address.DeviceId)); ci.LoginType = NDASCOMM_LOGIN_TYPE_NORMAL; COMVERIFY(m_pParentNdasDevice->get_HardwarePassword(&ci.OEMCode.UI64Value)); ci.Protocol = NDASCOMM_TRANSPORT_LPX; ci.UnitNo = m_unitDeviceId.UnitNo; ci.WriteAccess = FALSE; ci.BindingSocketAddressList = &localAddressList; *ndasHandle = ::NdasCommConnect(&ci); if (NULL == *ndasHandle) { HRESULT hr = AtlHresultFromLastError(); XTLTRACE2(NDASSVC_NDASCOMM, TRACE_LEVEL_ERROR, "NdasCommConnect failed, hr=0x%X\n", hr); return hr; } return S_OK; }
STDMETHODIMP CNdasDiskUnit::IsDibUnchanged() { CAutoInstanceLock autolock(this); CNdasUnitDeviceFactory ndasUnitFactory(m_pParentNdasDevice, m_unitDeviceId.UnitNo); CComPtr<INdasUnit> pCurrentNdasUnit; HRESULT hr = ndasUnitFactory.CreateUnitDevice(&pCurrentNdasUnit); if (FAILED(hr)) { XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_ERROR, "Recreating an NdasUnit failed, hr=0x%X\n", hr); return E_FAIL; } NDAS_UNITDEVICE_TYPE currentType; COMVERIFY(pCurrentNdasUnit->get_Type(¤tType)); if (m_type != currentType) { return E_FAIL; } CComQIPtr<INdasDiskUnit> pCurrentNdasDiskUnit = pCurrentNdasUnit; ATLASSERT(pCurrentNdasDiskUnit.p); NDAS_DIB_V2 currentDibV2; COMVERIFY(pCurrentNdasDiskUnit->get_Dib(¤tDibV2)); ATLASSERT(NULL != m_pDIBv2); int cmp = memcmp(m_pDIBv2, ¤tDibV2, sizeof(NDAS_DIB_V2)); if (0 != cmp) { return E_FAIL; } return S_OK; }
int _tWinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPTSTR lpCmdLine, __in int nShowCmd ) { COMVERIFY(CoInitialize(NULL)); // this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used (void) DefWindowProc(NULL, 0, 0, 0L); // add flags to support other controls ATLVERIFY(AtlInitCommonControls(ICC_WIN95_CLASSES | ICC_INTERNET_CLASSES)); COMVERIFY(_Module.Init(NULL, hInstance)); int retCode = -1; if (!VerifyNdasComm()) { AtlMessageBox( NULL, IDS_NDASCOMM_NOT_AVAILABLE, IDS_APP_ERROR_TITLE, MB_OK | MB_ICONSTOP); } else { ATLVERIFY( NdasCommInitialize() ); retCode = Run(lpCmdLine, nShowCmd); ATLVERIFY( NdasCommUninitialize() ); } _Module.Term(); CoUninitialize(); return retCode; }
STDMETHODIMP CNdasDiskUnit::FillBlockAcl(__in PVOID BlockAcl) { PNDAS_BLOCK_ACL pNdasBlockAcl = (NDAS_BLOCK_ACL *)BlockAcl; PNDAS_BLOCK_ACE pNdasBlockAce = NULL; PBLOCK_ACCESS_CONTROL_LIST_ELEMENT pBACLE = NULL; if (!m_pBACL) { return S_FALSE; } if (!BlockAcl) { return S_FALSE; } UINT nBACLESkipped = 0; for (UINT i = 0; i < m_pBACL->ElementCount; i++) { ATLASSERT(FALSE); pBACLE = &m_pBACL->Elements[i]; if (!(pBACLE->AccessMask & BACL_ACCESS_MASK_PC_SYSTEM)) { nBACLESkipped++; continue; } pNdasBlockAce = &pNdasBlockAcl->BlockACEs[i - nBACLESkipped]; pNdasBlockAce->AccessMode |= (pBACLE->AccessMask & BACL_ACCESS_MASK_WRITE) ? NBACE_ACCESS_WRITE : 0; pNdasBlockAce->AccessMode |= (pBACLE->AccessMask & BACL_ACCESS_MASK_READ) ? NBACE_ACCESS_READ : 0; pNdasBlockAce->StartingOffset = pBACLE->ui64StartSector * 512; pNdasBlockAce->Length = pBACLE->ui64SectorCount * 512; XTLTRACE2(NDASSVC_NDASUNITDEVICE, TRACE_LEVEL_INFORMATION, "FillBACL() pNdasBlockAce : %x %I64d ~ %I64d\n", pNdasBlockAce->AccessMode, pNdasBlockAce->StartingOffset, pNdasBlockAce->Length); } DWORD blockAclLength; COMVERIFY(get_BlockAclSize(nBACLESkipped, &blockAclLength)); pNdasBlockAcl->Length = blockAclLength; pNdasBlockAcl->BlockACECnt = m_pBACL->ElementCount - nBACLESkipped; return S_OK; }
bool operator()(INdasLogicalUnit* pNdasLogicalUnit) const { NDAS_LOGICALDEVICE_STATUS status; COMVERIFY(pNdasLogicalUnit->get_Status(&status)); switch (status) { case NDAS_LOGICALDEVICE_STATUS_MOUNTED: case NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING: case NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING: return true; } return false; }
void CNdasEventMonitor::Attach(INdasDevice* pNdasDevice) { DWORD slotNo; COMVERIFY(pNdasDevice->get_SlotNo(&slotNo)); XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Attaching ndas device %d to the monitor\n", slotNo); // DEVICE WRITE LOCK REGION { XTL::CWriterLockHolder holder(m_NdasDeviceDataLock); m_NdasDevices.Add(pNdasDevice); } // DEVICE WRITE LOCK REGION }
HRESULT CNdasLogicalUnitManager::Unregister(INdasUnit* pNdasUnit) { XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_INFORMATION, "Unregistering NdasUnit=%p from LDM\n", pNdasUnit); if (NULL == pNdasUnit) { return E_POINTER; } CComPtr<INdasLogicalUnit> pNdasLogicalUnit; COMVERIFY(pNdasUnit->get_NdasLogicalUnit(&pNdasLogicalUnit)); DWORD luseq; COMVERIFY(pNdasUnit->get_LogicalUnitSequence(&luseq)); COMVERIFY(pNdasLogicalUnit->RemoveNdasUnitInstance(pNdasUnit)); DWORD instanceCount; COMVERIFY(pNdasLogicalUnit->get_NdasUnitInstanceCount(&instanceCount)); if (0 == instanceCount) { NDAS_LOGICALDEVICE_ID logicalUnitId; COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId)); NDAS_LOGICALDEVICE_GROUP logicalUnitDefinition; COMVERIFY(pNdasLogicalUnit->get_LogicalUnitDefinition(&logicalUnitDefinition)); LockInstance(); XTLVERIFY(1 == m_LogicalUnitDefinitionMap.erase(logicalUnitDefinition)); XTLVERIFY(1 == m_LogicalUnitIdMap.erase(logicalUnitId)); size_t count = m_NdasLogicalUnits.GetCount(); for (size_t i = 0; i < count; ++i) { INdasLogicalUnit* p = m_NdasLogicalUnits.GetAt(i); if (p == pNdasLogicalUnit) { m_NdasLogicalUnits.RemoveAt(i); break; } } XTLVERIFY(pDeallocateID(logicalUnitId)); UnlockInstance(); } return S_OK; }
void CNdasEventMonitor::Detach(INdasDevice* pNdasDevice) { DWORD slotNo; COMVERIFY(pNdasDevice->get_SlotNo(&slotNo)); XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Detaching ndas device %d from the monitor\n", slotNo); // DEVICE WRITE LOCK REGION { XTL::CWriterLockHolder holder(m_NdasDeviceDataLock); size_t count = m_NdasDevices.GetCount(); for (size_t index = 0; index < count; ++index) { INdasDevice* p = m_NdasDevices.GetAt(index); if (pNdasDevice == p) { m_NdasDevices.RemoveAt(index); break; } } } // DEVICE WRITE LOCK REGION }
void CComponentObj::UnregisterActiveObject() { ASSERT( registeractiveobjectret ); COMVERIFY( ::RevokeActiveObject(registeractiveobjectret, NULL) ); registeractiveobjectret = 0; }
BOOL CNdasDeviceRegistrar::Bootstrap() { BOOL fSuccess = FALSE; BOOL fMigrated = FALSE; // // Set bootstrapping flag to prevent multiple events // for DeviceSetChange Events // m_fBootstrapping = TRUE; TCHAR szSubcontainer[30] = {0}; for (DWORD i = 0; i < MAX_SLOT_NUMBER; ++i) { COMVERIFY(StringCchPrintf( szSubcontainer, 30, _T("%s\\%04d"), CFG_CONTAINER, i)); BOOL fAutoRegistered = FALSE; fSuccess = _NdasSystemCfg.GetValueEx( szSubcontainer, _T("AutoRegistered"), &fAutoRegistered); if (fSuccess && fAutoRegistered) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Deleting %ls\n", szSubcontainer); // Auto registered devices are not persistent // it is an error to show up here. // We just ignore those entries fSuccess = _NdasSystemCfg.DeleteContainer(szSubcontainer, TRUE); if (!fSuccess) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Deleting a RegKey=%ls failed, error=0x%X\n", szSubcontainer, GetLastError()); } continue; } DWORD cbUsed; NDAS_DEVICE_ID_REG_DATA regData = {0}; const NDASID_EXT_DATA* ndasIdExtension = NULL; fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("DeviceID2"), ®Data, sizeof(NDAS_DEVICE_ID_REG_DATA), &cbUsed); if (!fSuccess) { // // Non-extension data // fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("DeviceID"), ®Data.DeviceId, sizeof(regData.DeviceId), &cbUsed); // // ignore read fault - tampered or not exists // if (!fSuccess || cbUsed != sizeof(NDAS_DEVICE_ID)) { continue; } if (regData.DeviceId.VID == 0) { // Assume VID 0 is VID 1 to support registry entry created by older software(~3.11) regData.DeviceId.VID = 1; } } else { if (cbUsed != sizeof(NDAS_DEVICE_ID_REG_DATA)) { // // maybe more recent versions, unrecognized, ignore // continue; } ndasIdExtension = ®Data.NdasIdExtension; } DWORD regFlags; fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("RegFlags"), ®Flags, sizeof(regFlags)); if (!fSuccess) { regFlags = NDAS_DEVICE_REG_FLAG_NONE; } CNdasDevicePtr pDevice = Register( i, regData.DeviceId, regFlags, ndasIdExtension); // This may happen due to auto-register feature! if (CNdasDeviceNullPtr == pDevice) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Registration failed for %s, error=0x%X\n", CNdasDeviceId(regData.DeviceId).ToStringA(), GetLastError()); // // During bootstrapping register may fail for unsupported VID. // In that case, we should retain this slot number to avoid // overwriting the existing data which may be created by // the higher version. // m_slotbit[i] = true; continue; } NDAS_OEM_CODE oemCode; fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("OEMCode"), &oemCode, sizeof(NDAS_OEM_CODE), &cbUsed); if (fSuccess && cbUsed == sizeof(NDAS_OEM_CODE)) { pDevice->SetOemCode(oemCode); } ACCESS_MASK grantedAccess = GENERIC_READ; const DWORD cbBuffer = sizeof(ACCESS_MASK) + sizeof(NDAS_DEVICE_ID); BYTE pbBuffer[cbBuffer]; fSuccess = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("GrantedAccess"), pbBuffer, cbBuffer); if (fSuccess) { grantedAccess = *((ACCESS_MASK*)(pbBuffer)); } grantedAccess |= GENERIC_READ; // to prevent invalid access mask configuration // XTLASSERT(grantedAccess & GENERIC_READ); // invalid configuration? pDevice->SetGrantedAccess(grantedAccess); TCHAR szDeviceName[MAX_NDAS_DEVICE_NAME_LEN + 1]; fSuccess = _NdasSystemCfg.GetValueEx( szSubcontainer, _T("DeviceName"), szDeviceName, sizeof(TCHAR)*(MAX_NDAS_DEVICE_NAME_LEN + 1)); if (fSuccess) { pDevice->SetName(szDeviceName); } BOOL fEnabled = FALSE; fSuccess = _NdasSystemCfg.GetValueEx( szSubcontainer, _T("Enabled"), &fEnabled); if (fSuccess && fEnabled) { pDevice->Enable(fEnabled); } } // // Migration will be done only once // if there is no registered devices in the current configurations // and if the migration flag (Install\Migrate = 1) is set // if (m_deviceSlotMap.size() == 0) { fSuccess = _NdasSystemCfg.GetValueEx(_T("Install"), _T("Migrated"), &fMigrated); if (!fSuccess || !fMigrated) { fMigrated = TRUE; ImportLegacySettings(); _NdasSystemCfg.SetValueEx(_T("Install"), _T("Migrated"), fMigrated); } } // // Clear bootstrapping state // m_fBootstrapping = FALSE; return TRUE; }
BOOL CNdasDeviceRegistrar::pImportLegacyEntry(DWORD SlotNo, HKEY hEntryKey) { static CONST size_t CB_ADDR = sizeof(TCHAR) * 18; HRESULT hr = E_FAIL; TCHAR szAddrVal[CB_ADDR + 1]; DWORD cbAddrVal = sizeof(szAddrVal); DWORD dwValueType; LONG lResult = ::RegQueryValueEx( hEntryKey, _T("Address"), 0, &dwValueType, (LPBYTE)szAddrVal, &cbAddrVal); if (ERROR_SUCCESS != lResult) { // Ignore invalid values return FALSE; } if (cbAddrVal != CB_ADDR) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Invalid Entry(A): %ls, ignored\n", szAddrVal); return FALSE; } // // 00:0B:D0:00:D4:2F to NDAS_DEVICE_ID // NDAS_DEVICE_ID deviceId = {0}; BOOL success = pConvertStringToDeviceId(szAddrVal, &deviceId); if (!success) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Invalid Entry(D): %ls, ignored\n", szAddrVal); return FALSE; } XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Importing an entry: %s\n", CNdasDeviceId(deviceId).ToStringA()); TCHAR szNameVal[MAX_NDAS_DEVICE_NAME_LEN + 1] = {0}; DWORD cbNameVal = sizeof(szNameVal); lResult = ::RegQueryValueEx( hEntryKey, _T("Name"), 0, &dwValueType, (LPBYTE)szNameVal, &cbNameVal); if (ERROR_SUCCESS != lResult || _T('\0') == szNameVal[0]) { TCHAR szDefaultName[MAX_NDAS_DEVICE_NAME_LEN + 1] = {0}; success = _NdasSystemCfg.GetValueEx( _T("Devices"), _T("DefaultPrefix"), szDefaultName, sizeof(szDefaultName)); if (!success) { COMVERIFY( StringCchCopy( szDefaultName, MAX_NDAS_DEVICE_NAME_LEN + 1, _T("NDAS Device ")) ); } hr = ::StringCchPrintf( szNameVal, MAX_NDAS_DEVICE_NAME_LEN, _T("%s %d"), szDefaultName, SlotNo); } BYTE pbSerialKeyVal[9]; DWORD cbSerialKeyVal = sizeof(pbSerialKeyVal); lResult = ::RegQueryValueEx( hEntryKey, _T("SerialKey"), 0, &dwValueType, (LPBYTE)pbSerialKeyVal, &cbSerialKeyVal); if (ERROR_SUCCESS != lResult) { return FALSE; } if (cbSerialKeyVal != sizeof(pbSerialKeyVal)) { return FALSE; } ACCESS_MASK fAccessMode = GENERIC_READ; if (0xFF == pbSerialKeyVal[8]) { // Registered as RW fAccessMode |= GENERIC_WRITE; } else if (0x00 == pbSerialKeyVal[8]) { // Registered as RO } else { // Invalid value return FALSE; } // // Register function returns the locked pointer // CComPtr<INdasDevice> pNdasDevice; hr = Register( SlotNo, deviceId, 0, NULL, CComBSTR(szNameVal), fAccessMode, NULL, &pNdasDevice); if (FAILED(hr)) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Failed to register %s at %d during import, error=0x%X", CNdasDeviceId(deviceId).ToStringA(), SlotNo, hr); return FALSE; } // Always enable this! COMVERIFY(pNdasDevice->put_Enabled(TRUE)); return TRUE; }
STDMETHODIMP CNdasDeviceRegistrar::Deregister(INdasDevice* pNdasDevice) { NDAS_DEVICE_ID ndasDeviceId; HRESULT hr; COMVERIFY(hr = pNdasDevice->get_NdasDeviceId(&ndasDeviceId)); if (FAILED(hr)) { return hr; } DWORD slotNo; COMVERIFY(hr = pNdasDevice->get_SlotNo(&slotNo)); XTLASSERT(0 != slotNo); NDAS_DEVICE_STATUS status; COMVERIFY(pNdasDevice->get_Status(&status)); if (NDAS_DEVICE_STATUS_DISABLED != status) { return NDASSVC_ERROR_CANNOT_UNREGISTER_ENABLED_DEVICE; } CAutoLock<CLock> autolock(&m_DataLock); XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Unregister device %s\n", CNdasDeviceId(ndasDeviceId).ToStringA()); bool found = false; size_t count = m_NdasDevices.GetCount(); for (size_t i = 0; i < count; ++i) { CComPtr<INdasDevice> p = m_NdasDevices.GetAt(i); if (p == pNdasDevice) { m_NdasDevices.RemoveAt(i); found = true; break; } } if (!found) { return NDASSVC_ERROR_DEVICE_ENTRY_NOT_FOUND; } DeviceIdMap::iterator itrId = m_deviceIdMap.find(ndasDeviceId); ATLASSERT(m_deviceIdMap.end() != itrId); DeviceSlotMap::iterator itrSlot = m_deviceSlotMap.find(slotNo); ATLASSERT(m_deviceSlotMap.end() != itrSlot); m_deviceIdMap.erase(itrId); m_deviceSlotMap.erase(itrSlot); m_slotbit[slotNo] = false; XTL::CStaticStringBuffer<30> containerName(_T("Devices\\%04d"), slotNo); BOOL success = _NdasSystemCfg.DeleteContainer(containerName, TRUE); if (!success) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING, "Deleting registration entry from the registry failed at %ls, error=0x%X\n", containerName, GetLastError()); } autolock.Release(); (void) pGetNdasEventPublisher().DeviceEntryChanged(); return S_OK; }
HRESULT CNdasLogicalUnitManager::Register(INdasUnit* pNdasUnit, INdasLogicalUnit** ppNdasLogicalUnit) { HRESULT hr; XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_INFORMATION, "Registering NdasUnit=%p to LDM\n", pNdasUnit); *ppNdasLogicalUnit = NULL; NDAS_LOGICALDEVICE_GROUP ludef; COMVERIFY(pNdasUnit->get_LogicalUnitDefinition(&ludef)); DWORD luseq; COMVERIFY(pNdasUnit->get_LogicalUnitSequence(&luseq)); CComPtr<INdasLogicalUnit> pNdasLogicalUnit; LockInstance(); LogicalDeviceGroupMap::iterator itr = m_LogicalUnitDefinitionMap.find(ludef); if (itr == m_LogicalUnitDefinitionMap.end()) { // // New Logical Device Instance // NDAS_LOGICALDEVICE_ID id = pAllocateID(); if (0 == id) { UnlockInstance(); // SLOT FULL hr = NDASSVC_ERROR_LOGICALDEVICE_SLOT_FULL; return hr; } CComObject<CNdasLogicalUnit>* pNdasLogicalUnitInstance; hr = CComObject<CNdasLogicalUnit>::CreateInstance(&pNdasLogicalUnitInstance); if (FAILED(hr)) { XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_ERROR, "CNdasLogicalUnit::CreateInstance failed, hr=0x%X\n", hr); UnlockInstance(); return hr; } hr = pNdasLogicalUnitInstance->Initialize(id, ludef); if (FAILED(hr)) { XTLTRACE2(NDASSVC_NDASLOGDEVMANAGER, TRACE_LEVEL_ERROR, "CNdasLogicalUnit::Initialize failed, hr=0x%X\n", hr); UnlockInstance(); return hr; } pNdasLogicalUnit = pNdasLogicalUnitInstance; m_NdasLogicalUnits.Add(pNdasLogicalUnit); m_LogicalUnitDefinitionMap.insert(std::make_pair(ludef, pNdasLogicalUnit)); m_LogicalUnitIdMap.insert(std::make_pair(id, pNdasLogicalUnit)); UnlockInstance(); CComPtr<INdasDevice> pNdasDevice; COMVERIFY(pNdasUnit->get_ParentNdasDevice(&pNdasDevice)); XTLASSERT(pNdasDevice); DWORD regFlags; COMVERIFY(pNdasDevice->get_RegisterFlags(®Flags)); if (regFlags & NDAS_DEVICE_REG_FLAG_AUTO_REGISTERED) { BOOL fMountOnReady = TRUE; if (NdasServiceConfig::Get(nscMountOnReadyForEncryptedOnly)) { NDAS_UNITDEVICE_TYPE unitType; COMVERIFY(pNdasUnit->get_Type(&unitType)); if (0 == luseq && NDAS_UNITDEVICE_TYPE_DISK == unitType) { CComQIPtr<INdasDiskUnit> pNdasDiskUnit(pNdasUnit); ATLASSERT(pNdasDiskUnit.p); NDAS_CONTENT_ENCRYPT encryption; COMVERIFY(pNdasDiskUnit->get_ContentEncryption(&encryption)); if (NDAS_CONTENT_ENCRYPT_METHOD_NONE != encryption.Method) { fMountOnReady = TRUE; } else { fMountOnReady = FALSE; } } } // auto registered devices always ignore RiskyMountFlag pNdasLogicalUnit->SetRiskyMountFlag(FALSE); if (fMountOnReady) { ACCESS_MASK granted; pNdasDevice->get_GrantedAccess(&granted); pNdasLogicalUnit->SetMountOnReady(granted, FALSE); } } } else { pNdasLogicalUnit = itr->second; UnlockInstance(); } COMVERIFY(pNdasLogicalUnit->AddNdasUnitInstance(pNdasUnit)); *ppNdasLogicalUnit = pNdasLogicalUnit.Detach(); return S_OK; }
STDMETHODIMP CNdasDeviceRegistrar::Register( __in_opt DWORD SlotNo, __in const NDAS_DEVICE_ID& DeviceId, __in DWORD RegFlags, __in_opt const NDASID_EXT_DATA* NdasIdExtension, __in BSTR Name, __in ACCESS_MASK GrantedAccess, __in_opt const NDAS_OEM_CODE* NdasOemCode, __deref_out INdasDevice** ppNdasDevice) { HRESULT hr; *ppNdasDevice = 0; NDAS_DEVICE_ID ndasDeviceId = DeviceId; // // this will lock this class from here // and releases the lock when the function returns; // CAutoLock<CLock> autolock(&m_DataLock); XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Registering device %s at slot %d\n", CNdasDeviceId(DeviceId).ToStringA(), SlotNo); if (NULL == NdasIdExtension) { NdasIdExtension = &NDAS_ID_EXTENSION_DEFAULT; } // // Only DEFAULT and SEAGATE are currently implemented // if (NDAS_VID_SEAGATE != NdasIdExtension->VID && NDAS_VID_WINDWOS_RO != NdasIdExtension->VID && NDAS_VID_DEFAULT != NdasIdExtension->VID) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Unknown Vendor ID=0x%02X\n", NdasIdExtension->VID); hr = NDASSVC_ERROR_UNKNOWN_VENDOR_ID; return hr; } ndasDeviceId.VID = NdasIdExtension->VID; // If SlotNo is zero, automatically assign it. // check slot number if (0 == SlotNo) { SlotNo = pLookupEmptySlot(); if (0 == SlotNo) { return NDASSVC_ERROR_DEVICE_ENTRY_SLOT_FULL; } } else if (SlotNo > MAX_SLOT_NUMBER) { return NDASSVC_ERROR_INVALID_SLOT_NUMBER; } // check and see if the slot is occupied if (m_slotbit[SlotNo]) { return NDASSVC_ERROR_SLOT_ALREADY_OCCUPIED; } // find an duplicate address { CComPtr<INdasDevice> pExistingDevice; if (SUCCEEDED(get_NdasDevice(&ndasDeviceId, &pExistingDevice))) { return NDASSVC_ERROR_DUPLICATE_DEVICE_ENTRY; } } // register CComObject<CNdasDevice>* pNdasDeviceInstance; hr = CComObject<CNdasDevice>::CreateInstance(&pNdasDeviceInstance); if (FAILED(hr)) { return hr; } hr = pNdasDeviceInstance->Initialize( SlotNo, ndasDeviceId, RegFlags, NdasIdExtension); if (FAILED(hr)) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Device initialization failed, error=0x%X\n", GetLastError()); return hr; } CComPtr<INdasDevice> pNdasDevice(pNdasDeviceInstance); COMVERIFY(pNdasDevice->put_Name(Name)); COMVERIFY(pNdasDevice->put_GrantedAccess(GrantedAccess)); if (NdasOemCode) { COMVERIFY(pNdasDevice->put_OemCode(NdasOemCode)); } m_slotbit[SlotNo] = true; bool insertResult; m_NdasDevices.Add(pNdasDevice); XTLVERIFY( m_deviceSlotMap.insert(std::make_pair(SlotNo, pNdasDevice)).second ); //DeviceSlotMap::value_type(SlotNo, pNdasDevice)).second; XTLVERIFY( m_deviceIdMap.insert(std::make_pair(ndasDeviceId, pNdasDevice)).second ); //DeviceIdMap::value_type(ndasDeviceId, pNdasDevice)).second; XTLASSERT(m_deviceSlotMap.size() == m_deviceIdMap.size()); // // When NdasIdExtension is NULL, NDAS_ID_EXTENSION_DEFAULT is assigned already // if (RegFlags & NDAS_DEVICE_REG_FLAG_VOLATILE) { } else { BOOL success; XTL::CStaticStringBuffer<30> containerName(_T("Devices\\%04d"), SlotNo); if (0 != memcmp(&NDAS_ID_EXTENSION_DEFAULT, NdasIdExtension, sizeof(NDASID_EXT_DATA))) { NDAS_DEVICE_ID_REG_DATA regData = {0}; regData.DeviceId = ndasDeviceId; regData.NdasIdExtension = *NdasIdExtension; success = _NdasSystemCfg.SetSecureValueEx( containerName, _T("DeviceID2"), ®Data, sizeof(regData)); } else { success = _NdasSystemCfg.SetSecureValueEx( containerName, _T("DeviceID"), &ndasDeviceId, sizeof(ndasDeviceId)); } if (!success) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING, "Writing registration entry to the registry failed at %ls, error=0x%X\n", containerName.ToString(), GetLastError()); } success = _NdasSystemCfg.SetSecureValueEx( containerName, _T("RegFlags"), &RegFlags, sizeof(RegFlags)); if (!success) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_WARNING, "Writing registration entry to the registry failed at %ls, error=0x%X\n", containerName.ToString(), GetLastError()); } } BOOL publishEvent = !m_fBootstrapping; autolock.Release(); // // During bootstrapping, we do not publish this event // Bootstrap process will publish an event later // if (publishEvent) { (void) pGetNdasEventPublisher().DeviceEntryChanged(); } *ppNdasDevice = pNdasDevice.Detach(); return S_OK; }
STDMETHODIMP CNdasDeviceRegistrar::Bootstrap() { HRESULT hr; BOOL success = FALSE; BOOL fMigrated = FALSE; // // Set bootstrapping flag to prevent multiple events // for DeviceSetChange Events // m_fBootstrapping = TRUE; TCHAR szSubcontainer[30] = {0}; for (DWORD i = 0; i < MAX_SLOT_NUMBER; ++i) { COMVERIFY(StringCchPrintf( szSubcontainer, 30, _T("%s\\%04d"), CFG_CONTAINER, i)); BOOL fAutoRegistered = FALSE; success = _NdasSystemCfg.GetValueEx( szSubcontainer, _T("AutoRegistered"), &fAutoRegistered); if (success && fAutoRegistered) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Deleting %ls\n", szSubcontainer); // Auto registered devices are not persistent // it is an error to show up here. // We just ignore those entries success = _NdasSystemCfg.DeleteContainer(szSubcontainer, TRUE); if (!success) { XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_INFORMATION, "Deleting a RegKey=%ls failed, error=0x%X\n", szSubcontainer, GetLastError()); } continue; } DWORD cbUsed; NDAS_DEVICE_ID_REG_DATA regData = {0}; const NDASID_EXT_DATA* ndasIdExtension = NULL; success = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("DeviceID2"), ®Data, sizeof(NDAS_DEVICE_ID_REG_DATA), &cbUsed); if (!success) { // // Non-extension data // success = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("DeviceID"), ®Data.DeviceId, sizeof(regData.DeviceId), &cbUsed); // // ignore read fault - tampered or not exists // if (!success || cbUsed != sizeof(NDAS_DEVICE_ID)) { continue; } // For VID's other than 1 (or 0), DeviceID2 should be used instead. // In this case, VID is 1. // (Assume VID 0 is VID 1 to support registry entry created // by older software(~3.11)) regData.DeviceId.VID = 1; } else { if (cbUsed != sizeof(NDAS_DEVICE_ID_REG_DATA)) { // // maybe more recent versions, unrecognized, ignore // continue; } // DeviceId.VID may not be written correctly by some version of SW. regData.DeviceId.VID = regData.NdasIdExtension.VID; ndasIdExtension = ®Data.NdasIdExtension; } // // RegFlags // DWORD regFlags; success = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("RegFlags"), ®Flags, sizeof(regFlags)); if (!success) { regFlags = NDAS_DEVICE_REG_FLAG_NONE; } // // NDAS OEM Code // const NDAS_OEM_CODE* ndasOemCode = NULL; NDAS_OEM_CODE ndasOemCodeBuffer; success = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("OEMCode"), &ndasOemCodeBuffer, sizeof(NDAS_OEM_CODE), &cbUsed); if (success && cbUsed == sizeof(NDAS_OEM_CODE)) { ndasOemCode = &ndasOemCodeBuffer; } // // Granted Access // ACCESS_MASK grantedAccess = GENERIC_READ; const DWORD cbBuffer = sizeof(ACCESS_MASK) + sizeof(NDAS_DEVICE_ID); BYTE pbBuffer[cbBuffer]; success = _NdasSystemCfg.GetSecureValueEx( szSubcontainer, _T("GrantedAccess"), pbBuffer, cbBuffer); if (success) { grantedAccess = *((ACCESS_MASK*)(pbBuffer)); } grantedAccess |= GENERIC_READ; // to prevent invalid access mask configuration // // NDAS Device Name // TCHAR szDeviceName[MAX_NDAS_DEVICE_NAME_LEN + 1]; success = _NdasSystemCfg.GetValueEx( szSubcontainer, _T("DeviceName"), szDeviceName, sizeof(TCHAR)*(MAX_NDAS_DEVICE_NAME_LEN + 1)); if (!success) { COMVERIFY(StringCchCopy( szDeviceName, RTL_NUMBER_OF(szDeviceName), _T("NDAS Device"))); } // // Register // CComPtr<INdasDevice> pNdasDevice; hr = Register( i, regData.DeviceId, regFlags, ndasIdExtension, CComBSTR(szDeviceName), grantedAccess, ndasOemCode, &pNdasDevice); if (FAILED(hr)) { // // This may happen due to auto-register feature! // XTLTRACE2(NDASSVC_NDASDEVICEREGISTRAR, TRACE_LEVEL_ERROR, "Registration failed for %s, hr=0x%X\n", CNdasDeviceId(regData.DeviceId).ToStringA(), hr); // // During bootstrapping register may fail for unsupported VID. // In that case, we should retain this slot number to avoid // overwriting the existing data which may be created by // the higher version. // m_slotbit[i] = true; continue; } BOOL fEnabled = FALSE; success = _NdasSystemCfg.GetValueEx( szSubcontainer, _T("Enabled"), &fEnabled); if (success && fEnabled) { COMVERIFY(pNdasDevice->put_Enabled(fEnabled)); } } // // Migration will be done only once // if there is no registered devices in the current configurations // and if the migration flag (Install\Migrate = 1) is set // if (m_deviceSlotMap.size() == 0) { success = _NdasSystemCfg.GetValueEx(_T("Install"), _T("Migrated"), &fMigrated); if (!success || !fMigrated) { fMigrated = TRUE; pImportLegacySettings(); _NdasSystemCfg.SetValueEx(_T("Install"), _T("Migrated"), fMigrated); } } // // Clear bootstrapping state // m_fBootstrapping = FALSE; return S_OK; }
// // Return TRUE to grant the request to suspend. // To deny the request, return BROADCAST_QUERY_DENY. // LRESULT CNdasServicePowerEventHandler::OnQuerySuspend(DWORD dwFlags) { HRESULT hr; XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_INFORMATION, "OnQuerySuspend.\n"); // A DWORD value dwFlags specifies action flags. // If bit 0 is 1, the application can prompt the user for directions // on how to prepare for the suspension; otherwise, the application // must prepare without user interaction. All other bit values are reserved. DWORD dwValue = NdasServiceConfig::Get(nscSuspendOptions); if (NDASSVC_SUSPEND_ALLOW == dwValue) { return TRUE; } CComPtr<INdasLogicalUnitManager> pManager; COMVERIFY(hr = pGetNdasLogicalUnitManager(&pManager)); CInterfaceArray<INdasLogicalUnit> ndasLogicalUnits; pManager->get_NdasLogicalUnits(NDAS_ENUM_DEFAULT, ndasLogicalUnits); bool mounted = false; size_t count = ndasLogicalUnits.GetCount(); for (size_t index = 0; index < count; ++index) { INdasLogicalUnit* pNdasLogicalUnit = ndasLogicalUnits.GetAt(index); if (LogicalDeviceIsMounted()(pNdasLogicalUnit)) { mounted = true; break; } } // // Service won't interact with the user // If you want to make this function interactive // You should set the NDASSVC_SUSPEND_ALLOW // and the UI application should process NDASSVC_SUSPEND by itself // if (mounted) { if (0x01 == (dwFlags & 0x01)) { // // Possible to interact with the user // (void) m_service.GetEventPublisher().SuspendRejected(); return BROADCAST_QUERY_DENY; } else { // // No User interface is available // (void) m_service.GetEventPublisher().SuspendRejected(); return BROADCAST_QUERY_DENY; } } return TRUE; }
BOOL CNdasAutoRegister::ProcessRegister( const NDAS_DEVICE_ID& deviceId, ACCESS_MASK autoRegAccess) { HRESULT hr; CComPtr<INdasDeviceRegistrar> pRegistrar; COMVERIFY(hr = pGetNdasDeviceRegistrar(&pRegistrar)); if (FAILED(hr)) { return FALSE; } CComPtr<INdasDevice> pExistingDevice; hr = pRegistrar->get_NdasDevice(&const_cast<NDAS_DEVICE_ID&>(deviceId), &pExistingDevice); if (SUCCEEDED(hr)) { return TRUE; } DWORD dwRegFlags = NDAS_DEVICE_REG_FLAG_AUTO_REGISTERED | NDAS_DEVICE_REG_FLAG_VOLATILE; // // Register function returns the locked pointer // CComPtr<INdasDevice> pNdasDevice; hr = pRegistrar->Register( 0, deviceId, dwRegFlags, NULL, CComBSTR(L"NDAS Device"), autoRegAccess, NULL, &pNdasDevice); if (FAILED(hr)) { XTLTRACE2(NDASSVC_AUTOREG, TRACE_LEVEL_ERROR, "Register failed, hr=0x%X\n", hr); return FALSE; } DWORD slotNo; COMVERIFY(pNdasDevice->get_SlotNo(&slotNo)); CComBSTR ndasDeviceName(MAX_NDAS_DEVICE_NAME_LEN + 1); COMVERIFY(StringCchPrintfW( ndasDeviceName, MAX_NDAS_DEVICE_NAME_LEN + 1, L"NDAS Device A%04d", slotNo)); COMVERIFY(pNdasDevice->put_Name(ndasDeviceName)); hr = pNdasDevice->put_Enabled(TRUE); if (FAILED(hr)) { XTLTRACE2(NDASSVC_AUTOREG, TRACE_LEVEL_ERROR, "Enable failed, hr=0x%X\n", hr); } return TRUE; }
void CNdasEventMonitor::OnLogicalDeviceAlarmed(INdasLogicalUnit* pNdasLogicalUnit) { NDAS_LOCATION ndasLocation; COMVERIFY(pNdasLogicalUnit->get_Id(&ndasLocation)); NDAS_LOGICALUNIT_ADDRESS ndasLogicalUnitAddress; COMVERIFY(pNdasLogicalUnit->get_LogicalUnitAddress(&ndasLogicalUnitAddress)); XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Alarm Event, ndasLocation=%d, logicalUnit=%p\n", ndasLocation, pNdasLogicalUnit); if (0 == ndasLocation) { XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR, "Invalid SCSI Location\n"); XTLASSERT(FALSE); return; } ULONG newAdapterStatus; while(TRUE) { BOOL success = ::NdasBusCtlQueryEvent( ndasLocation, &newAdapterStatus); if (!success) { if (::GetLastError() == ERROR_NO_MORE_ITEMS) { XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "No more events, ignored, ndasLocation=%d\n", ndasLocation); } else { XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_ERROR, "Query status failed on alarm, ignored, ndasLocation=%d\n", ndasLocation); } return; } XTLTRACE2(NDASSVC_EVENTMON, TRACE_LEVEL_INFORMATION, "Logical device alarmed, ndasLocation=%d, adapterStatus=%08X.\n", ndasLocation, newAdapterStatus); // Determine whether an alarm will be issued. // Only viable alarm will be published ULONG currentAdapterStatus; COMVERIFY(pNdasLogicalUnit->get_AdapterStatus(¤tAdapterStatus)); if (pIsViableAlarmStatus(currentAdapterStatus, newAdapterStatus)) { CNdasEventPublisher& epub = pGetNdasEventPublisher(); NDAS_LOGICALDEVICE_ID logicalUnitId; COMVERIFY(pNdasLogicalUnit->get_Id(&logicalUnitId)); (void) epub.LogicalDeviceAlarmed( logicalUnitId, pGetSignificantAlarm(currentAdapterStatus, newAdapterStatus)); } COMVERIFY(pNdasLogicalUnit->put_AdapterStatus(newAdapterStatus)); if (!ADAPTERINFO_ISSTATUSFLAG( newAdapterStatus, NDASSCSI_ADAPTER_STATUSFLAG_NEXT_EVENT_EXIST)) { break; } } }
result_type operator()(argument_type pNdasLogicalUnit) const { HANDLE h; COMVERIFY(pNdasLogicalUnit->get_AlarmEvent(&h)); return h; }