BOOL CNdasDevice::UpdateDeviceInfo() { ximeta::CAutoLock autolock(this); if (NDAS_DEVICE_STATUS_CONNECTED != m_status) { return FALSE; } BOOL fSuccess = GetDeviceInfo( m_localLpxAddress, m_remoteLpxAddress, GetHWType(), GetHWVersion()); if (!fSuccess) { BOOL fDisconnectable = DestroyAllUnitDevices(); if (fDisconnectable) { DBGPRT_INFO(_FT("%s: Changing to DISCONNECTED.\n"), ToString()); ChangeStatus(NDAS_DEVICE_STATUS_DISCONNECTED); } else { DBGPRT_INFO(_T("%s: Some unit devices are mounted!\n"), ToString()); } return FALSE; } return TRUE; }
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: XDbgInit(_T("NDMSICA")); XDbgLoadSettingsFromRegistry( _T("Software\\NDAS\\NDMSICA"), HKEY_CURRENT_USER); DBGPRT_INFO(_FT("NDMSICA.DLL Process Attach\n")); break; case DLL_THREAD_ATTACH: DBGPRT_INFO(_FT("NDMSICA.DLL Thread Attach\n")); break; case DLL_THREAD_DETACH: DBGPRT_INFO(_FT("NDMSICA.DLL Thread Detach\n")); break; case DLL_PROCESS_DETACH: DBGPRT_INFO(_FT("NDMSICA.DLL Process Detach\n")); XDbgCleanup(); break; } return TRUE; }
static BOOL pIsUpdateRequiredVersion( LPTSTR szFilename, ULONG ulMinVer) { // get version of update package DWORD dwUpdateMSVer; DWORD dwRet = GetFileVersionNumber(szFilename, &dwUpdateMSVer, NULL); if (ERROR_SUCCESS != dwRet) { // can't obtain version information; assume not proper version DBGPRT_INFO(_FT("Can't obtain version information for update package;") _T("assuming it is not the proper version\n")); return FALSE; } // compare version at source to required minimum ULONG ulSourceVer = HIWORD(dwUpdateMSVer) * 100 + LOWORD(dwUpdateMSVer); if (ulSourceVer < ulMinVer) { // source version won't get us to our minimum version DBGPRT_INFO(_FT("The update package is improper version for upgrade.") _T("Update package Version = %d, Minimum Version = %d.\n"), ulSourceVer, ulMinVer); return FALSE; } return TRUE; }
BOOL CNdasLogicalDevice::Unplug() { BOOL fSuccess(FALSE); ximeta::CAutoLock autolock(this); DBGPRT_INFO(_FT("Unplugging %s\n"), ToString()); if (m_status == NDAS_LOGICALDEVICE_STATUS_NOT_INITIALIZED) { ::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_NOT_INITIALIZED); return FALSE; } if (m_status != NDAS_LOGICALDEVICE_STATUS_MOUNTED && m_status != NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING && m_status != NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING) { ::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_NOT_MOUNTED); return FALSE; } // // Remove target ejects the disk and the volume. // fSuccess = LsBusCtlRemoveTarget(m_NdasScsiLocation.SlotNo); if (!fSuccess) { DBGPRT_WARN_EX(_FT("LsBusCtlRemoveTarget failed: ")); } // Intentional break ::Sleep(100); // // BUG: // What happened when RemoveTarget succeeded and // Unplugging LANSCSI port is failed? // fSuccess = LsBusCtlUnplug(m_NdasScsiLocation.SlotNo); if (!fSuccess) { DBGPRT_ERR_EX(_FT("LsBusCtlUnplug failed: ")); // last error from lsbusctl unplug return FALSE; } // // Change the status to unmounted // SetStatus(NDAS_LOGICALDEVICE_STATUS_UNMOUNTED); DBGPRT_INFO(_FT("Unplugged successfully at slot %s.\n"), CNdasScsiLocation(m_NdasScsiLocation).ToString()); return TRUE; }
BOOL WINAPI NdasDmGetVolumeNumberOfDriveLetter(int drvno, ULONG *vol) { BOOL bret = FALSE ; HANDLE volMgr ; TCHAR volName[] = _T("\\\\.\\A:") ; VOLUME_NUMBER VN ; ULONG retsz ; // // fix volume name // volName[4] += (TCHAR)drvno ; DBGPRT_INFO(_FT("DOS device name: %s\n"), volName); // // open the volume manager // volMgr = CreateFile(volName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) ; if(volMgr == INVALID_HANDLE_VALUE) { DBGPRT_ERR_EX(_FT("CreateFile(%s) failed: "), volName); return FALSE ; } bret = DeviceIoControl( volMgr, IOCTL_VOLUME_QUERY_VOLUME_NUMBER, NULL, // lpInBuffer 0, // size of input buffer (LPVOID) &VN, // output buffer (DWORD) sizeof(VN), // size of output buffer &retsz, // number of bytes returned NULL // OVERLAPPED structure ) ; if(bret == FALSE) { DBGPRT_ERR_EX(_FT("DeviceIoControl(IOCTL_VOLUME_QUERY_VOLUME_NUMBER) failed: ")); goto cleanup ; } DBGPRT_INFO(_FT("Volume Number:%d\n"), VN.VolumeNumber ); DBGPRT_INFO(_FT("Volume Manager Name:%ws\n"), VN.VolumeManagerName ); *vol = VN.VolumeNumber ; cleanup: if(volMgr != 0 && volMgr != INVALID_HANDLE_VALUE) CloseHandle(volMgr) ; return bret ; }
ULONG CNdasLogicalDevice::Release() { { ximeta::CAutoLock autolock(this); DBGPRT_INFO(_FT("%s\n"), ToString()); } ULONG ulCount = ximeta::CExtensibleObject::Release(); DBGPRT_INFO(_FT("RefCount=%u\n"), ulCount); return ulCount; }
ULONG CNdasDevice::Release() { { ximeta::CAutoLock autolock(this); DBGPRT_INFO(_FT("%s\n"), ToString()); } ULONG ulCount = ximeta::CExtensibleObject::Release(); // // After release there should be no member function calls! // The above block is to prevent autolock's dtor be called after this line // DBGPRT_INFO(_FT("RefCount=%u\n"), ulCount); return ulCount; }
VOID CNdasLogicalDevice::OnUnmounted() { ximeta::CAutoLock autolock(this); DBGPRT_INFO(_FT("%s: Unmount Completed%s.\n"), ToString(), m_fDisconnected ? _T(" (by disconnection)") : _T("")); SetStatus(NDAS_LOGICALDEVICE_STATUS_UNMOUNTED); m_dwMountTick = 0; if (!m_fDisconnected) { // clears the mount flag only on unmount by user's request SetLastMountAccess(0); } // clears the risky mount flag SetRiskyMountFlag(FALSE); // Detach from the event monitor pGetNdasEventMonitor()->Detach(this); // Check the status of parent devices of unit devices for (DWORD i = 0; i < m_logicalDeviceGroup.nUnitDevices; ++i) { CheckUnitDeviceOnUnmount(m_pUnitDevices[i]); } }
DWORD CNdasIXServer::OnTaskStart() { DBGPRT_INFO(_FT("Starting NdasIXServer.\n")); CLpxDatagramServer m_dgs; BOOL fSuccess = m_dgs.Initialize(); if (!fSuccess) { DBGPRT_ERR_EX(_FT("CNdasIXServer init failed: ")); return 255; } fSuccess = m_dgs.Receive( this, m_usListenPort, INFOX_MAX_DATAGRAM_PKT_SIZE, m_hTaskTerminateEvent); if (!fSuccess) { DBGPRT_ERR_EX(_FT("Listening IXServer at port %d failed: "), m_usListenPort); return 255; } return 0; }
BOOL CNdasUnitDevice::GetHostUsageCount( LPDWORD lpnROHosts, LPDWORD lpnRWHosts, BOOL fUpdate) { ximeta::CAutoLock autolock(this); _ASSERTE(!IsBadWritePtr(lpnROHosts, sizeof(DWORD))); _ASSERTE(!IsBadWritePtr(lpnRWHosts, sizeof(DWORD))); if (fUpdate) { BOOL fSuccess = m_pParentDevice->UpdateDeviceInfo(); if (!fSuccess) { DPErrorEx(_FT("Update device status failed: ")); return FALSE; } } *lpnROHosts = m_devInfo.dwROHosts; *lpnRWHosts = m_devInfo.dwRWHosts; DBGPRT_INFO(_FT("Host Usage Count: RO %d, RW %d.\n"), m_devInfo.dwROHosts, m_devInfo.dwRWHosts); return TRUE; }
VOID CNdasService::ServiceMain(DWORD dwArgc, LPTSTR* lpArgs) { m_bDebugMode = FALSE; BOOL fSuccess = this->ximeta::CTask::Initialize(); if (!fSuccess) { // TODO: Return appropriate error code for stopped // TODO: Event Log ReportStatusToSCMgr(SERVICE_STOPPED, 0, ::GetLastError()); return; } fSuccess = this->Run(); if (!fSuccess) { // TODO: Return appropriate error code for stopped // TODO: Event Log ReportStatusToSCMgr(SERVICE_STOPPED, 0, ::GetLastError()); return; } DBGPRT_INFO(_FT("NDAS Service is running...\n")); ReportStatusToSCMgr(SERVICE_RUNNING); return; }
BOOL WINAPI NdasDmGetScsiPortNumberOfDisk( IN DWORD dwPhysicalDiskNumber, OUT LPDWORD lpdwScsiPortNumber) { _ASSERTE(!IsBadWritePtr(lpdwScsiPortNumber, sizeof(DWORD))); // // make up Physical Drive Name // TCHAR szDiskDevicePath[_MAX_PATH + 1]; HRESULT hr = ::StringCchPrintf( szDiskDevicePath, _MAX_PATH + 1, _T("\\\\.\\PHYSICALDRIVE%d"), dwPhysicalDiskNumber); _ASSERT(SUCCEEDED(hr)); DBGPRT_INFO(_FT("Disk Device Path:%s\n"), szDiskDevicePath); // // open the disk device // DBGPRT_TRACE(_FT("CreateFile(%s)\n"), szDiskDevicePath); HANDLE hDisk = ::CreateFile( szDiskDevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hDisk) { DBGPRT_ERR_EX(_FT("CreateFile(%s) failed: "), szDiskDevicePath); return FALSE; } // // Get SCSI Port Number of the Disk // BOOL fSuccess = NdasDmGetScsiPortNumberOfDisk(hDisk, lpdwScsiPortNumber); if (!fSuccess) { DBGPRT_ERR(_FT("NdasDmGetScsiPortNumberOfDisk(%s) failed.\n"), szDiskDevicePath); (VOID) ::CloseHandle(hDisk); return FALSE; } (VOID) ::CloseHandle(hDisk); return TRUE; }
BOOL APIENTRY DllMain( HANDLE hModule, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: InitProcessData(); XDbgInit(_T("NDASUSER")); XDbgLoadSettingsFromRegistry( _T("Software\\NDAS\\NDASUSER"), HKEY_CURRENT_USER); DBGPRT_INFO(_FT("NDASUSER.DLL Process Attach\n")); _pEventSubscriber = new CNdasEventSubscriber(); break; case DLL_THREAD_ATTACH: DBGPRT_INFO(_FT("NDASUSER.DLL Thread Attach\n")); break; case DLL_THREAD_DETACH: DBGPRT_INFO(_FT("NDASUSER.DLL Thread Detach\n")); break; case DLL_PROCESS_DETACH: if (NULL != _pxdbgSystemDebugOutput) { delete _pxdbgSystemDebugOutput; } XDbgCleanup(); CleanupProcessData(); DBGPRT_INFO(_FT("NDASUSER.DLL Process Detach\n")); delete _pEventSubscriber; break; } return TRUE; }
ULONG CNdasUnitDevice::Release() { ximeta::CAutoLock autolock(this); ULONG ulCount = ximeta::CExtensibleObject::Release(); DBGPRT_INFO(_FT("AddRef Reference: %u\n"), ulCount); return ulCount; }
ULONG CNdasLogicalDevice::AddRef() { ximeta::CAutoLock autolock(this); ULONG ulCount = ximeta::CExtensibleObject::AddRef(); DBGPRT_INFO(_FT("%s: %u\n"), ToString(), ulCount); return ulCount; }
BOOL CNdasDevice::InvalidateUnitDevice(DWORD dwUnitNo) { ximeta::CAutoLock autoLock(this); DBGPRT_INFO(_FT("%s: Invalidating Unit Device %d\n"), ToString(), dwUnitNo); if (dwUnitNo >= MAX_NDAS_UNITDEVICE_COUNT) { DBGPRT_INFO(_T("%s: Invalid Unit No: %d\n"), ToString(), dwUnitNo); ::SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (NDAS_DEVICE_STATUS_CONNECTED != GetStatus()) { DBGPRT_INFO(_T("%s: Non-connected device ignored\n"), ToString()); return FALSE; } BOOL fSuccess = UpdateDeviceInfo(); if (!fSuccess) { DBGPRT_ERR_EX(_T("%s: Device is not available.\n"), ToString()); return FALSE; } fSuccess = DestroyUnitDevice(dwUnitNo); if (!fSuccess) { DBGPRT_ERR_EX(_FT("%s: Destroying unit device (%d) failed: "), ToString(), dwUnitNo); return FALSE; } fSuccess = CreateUnitDevice(dwUnitNo); if (!fSuccess) { DBGPRT_ERR_EX(_FT("%s: Creating unit device (%d) failed: "), ToString(), dwUnitNo); return FALSE; } DBGPRT_INFO(_FT("%s: Unit Device (%d) recreated\n"), ToString(), dwUnitNo); return TRUE; }
VOID CNdasDevice::ChangeStatus(NDAS_DEVICE_STATUS newStatus) { ximeta::CAutoLock autolock(this); if (m_status == newStatus) { return; } NDAS_DEVICE_STATUS oldStatus = m_status; // // clear failure count for every status change // m_dwCommFailureCount = 0; switch (newStatus) { case NDAS_DEVICE_STATUS_DISABLED: { pGetNdasDeviceHeartbeatListner()->Detach(this); pGetNdasEventMonitor()->Detach(this); DestroyAllUnitDevices(); } break; case NDAS_DEVICE_STATUS_CONNECTED: { pGetNdasEventMonitor()->Attach(this); } break; case NDAS_DEVICE_STATUS_DISCONNECTED: { // // Detaching from the Monitor will be done at OnStatusCheck // by returning TRUE to detach this device from the monitor // pGetNdasDeviceHeartbeatListner()->Attach(this); DestroyAllUnitDevices(); } break; default: _ASSERTE(FALSE); } DBGPRT_INFO(_FT("%s status changed %s to %s\n"), ToString(), NdasDeviceStatusString(m_status), NdasDeviceStatusString(newStatus)); m_status = newStatus; (VOID) pGetNdasEventPublisher()-> DeviceStatusChanged(m_dwSlotNo, oldStatus, newStatus); return; }
BOOL CNdasLogicalDevice::IsPSWriteShareCapable() { BOOL fNoPSWriteShare = FALSE; // global option BOOL fSuccess = _NdasSystemCfg.GetValueEx( _T("ndassvc"), _T("NoPSWriteShare"), &fNoPSWriteShare); if (fSuccess && fNoPSWriteShare) { DBGPRT_INFO(_FT("NoPSWriteShare is set as global.\n")); return FALSE; } // logical device specific option fSuccess = _NdasSystemCfg.GetValueEx( m_szRegContainer, _T("NoPSWriteShare"), &fNoPSWriteShare); if (fSuccess && fNoPSWriteShare) { DBGPRT_INFO(_FT("NoPSWriteShare is set at %s.\n"), ToString()); return FALSE; } // even though NoPSWriteShare is not set, if there is no active // LFS filter, then PSWriteShare is denied. WORD wNDFSMajor, wNDFSMinor; fSuccess = ::LfsFiltCtlGetVersion( NULL, NULL, NULL, NULL, &wNDFSMajor, &wNDFSMinor); if (!fSuccess) { // no LFS exists or it is not working NoPSWriteShare DBGPRT_INFO(_FT("LFSFilter does not exist. NoPSWriteShare.\n")); return FALSE; } return TRUE; }
BOOL CNdasEventPublisher::SuspendRejected() { NDAS_EVENT_MESSAGE msg = {0}; msg.MessageSize = sizeof(NDAS_EVENT_MESSAGE); msg.EventType = NDAS_EVENT_TYPE_SUSPEND_REJECTED; DBGPRT_INFO(_FT("Suspend Rejected Event.\n")); return AddEvent(msg); }
BOOL CNdasEventPublisher::ServiceTerminating() { NDAS_EVENT_MESSAGE msg = {0}; msg.MessageSize = sizeof(NDAS_EVENT_MESSAGE); msg.EventType = NDAS_EVENT_TYPE_TERMINATING; DBGPRT_INFO(_FT("Service Termination Event.\n")); return AddEvent(msg); }
BOOL CNdasEventPublisher::LogicalDeviceEntryChanged() { NDAS_EVENT_MESSAGE msg = {0}; msg.MessageSize = sizeof(NDAS_EVENT_MESSAGE); msg.EventType = NDAS_EVENT_TYPE_LOGICALDEVICE_ENTRY_CHANGED; DBGPRT_INFO(_FT("Logical Device Entry Changed\n")); return AddEvent(msg); }
VOID CNdasEventMonitor::Attach(CNdasDevice* pDevice) { ximeta::CAutoLock autolock(this); pDevice->AddRef(); DBGPRT_INFO(_FT("Attaching device %s to the monitor\n"), CNdasDeviceId(pDevice->GetDeviceId()).ToString()); std::pair<CNdasDeviceSet::iterator,bool> ins = m_hbMonDevices.insert(pDevice); }
BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: XDbgInit(_T("NDUPDATE")); XDbgLoadSettingsFromRegistry( _T("Software\\NDAS\\NDUpdate"), HKEY_CURRENT_USER); DBGPRT_INFO(_FT(DLL_NAME) _T(" Process Attach\n")); _NdasUpdateDllInstance = hModule; break; case DLL_THREAD_ATTACH: DBGPRT_INFO(_FT(DLL_NAME) _T(" Thread Attach\n")); break; case DLL_THREAD_DETACH: DBGPRT_INFO(_FT(DLL_NAME) _T(" Thread Detach\n")); break; case DLL_PROCESS_DETACH: DBGPRT_INFO(_FT(DLL_NAME) _T(" Process Detach\n")); XDbgCleanup(); break; } return TRUE; }
BOOL CNdasEventPublisher::LogicalDeviceEmergency( NDAS_LOGICALDEVICE_ID logicalDeviceId) { NDAS_EVENT_MESSAGE msg = {0}; msg.MessageSize = sizeof(NDAS_EVENT_MESSAGE); msg.EventType = NDAS_EVENT_TYPE_LOGICALDEVICE_EMERGENCY; msg.LogicalDeviceEventInfo.LogicalDeviceId = logicalDeviceId; DBGPRT_INFO(_FT("Logical Device (%d) is in fault mode.\n"), logicalDeviceId); return AddEvent(msg); }
BOOL CNdasEventPublisher::LogicalDeviceReconnected( NDAS_LOGICALDEVICE_ID logicalDeviceId) { NDAS_EVENT_MESSAGE msg = {0}; msg.MessageSize = sizeof(NDAS_EVENT_MESSAGE); msg.EventType = NDAS_EVENT_TYPE_LOGICALDEVICE_RECONNECTED; msg.LogicalDeviceEventInfo.LogicalDeviceId = logicalDeviceId; DBGPRT_INFO(_FT("Logical Device (%d) is alive.\n"), logicalDeviceId); return AddEvent(msg); }
BOOL CNdasEventPublisher::LogicalDeviceRelationChanged( NDAS_LOGICALDEVICE_ID logicalDeviceId) { NDAS_EVENT_MESSAGE msg = {0}; msg.MessageSize = sizeof(NDAS_EVENT_MESSAGE); msg.EventType = NDAS_EVENT_TYPE_LOGICALDEVICE_RELATION_CHANGED; msg.LogicalDeviceEventInfo.LogicalDeviceId = logicalDeviceId; DBGPRT_INFO(_FT("Logical Device (%d) Relation Changed.\n"), logicalDeviceId); return AddEvent(msg); }
BOOL CNdasEventPublisher::DevicePropertyChanged( DWORD slotNo) { NDAS_EVENT_MESSAGE msg = {0}; msg.MessageSize = sizeof(NDAS_EVENT_MESSAGE); msg.EventType = NDAS_EVENT_TYPE_DEVICE_PROPERTY_CHANGED; msg.DeviceEventInfo.SlotNo = slotNo; DBGPRT_INFO(_FT("Device (%d) Property Changed.\n"), slotNo); return AddEvent(msg); }
VOID CNdasLogicalDevice::OnUnmountFailed() { ximeta::CAutoLock autolock(this); DBGPRT_INFO(_FT("Unmount failure from logical device %s.\n"), ToString()); if (NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING == GetStatus()) { SetStatus(NDAS_LOGICALDEVICE_STATUS_MOUNTED); } }
BOOL CNdasLogicalDevice::Eject() { ximeta::CAutoLock autolock(this); DBGPRT_INFO(_FT("Ejecting %s\n"), ToString()); if (m_status == NDAS_LOGICALDEVICE_STATUS_NOT_INITIALIZED) { ::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_NOT_INITIALIZED); DBGPRT_ERR(_FT("Eject is requested to not initialized logical device")); return FALSE; } if (m_status != NDAS_LOGICALDEVICE_STATUS_MOUNTED) { ::SetLastError(NDASHLPSVC_ERROR_NDAS_LOGICALDEVICE_NOT_MOUNTED); DBGPRT_ERR(_FT("Eject is requested to not mounted logical device")); return FALSE; } BOOL fSuccess = ::LsBusCtlEject(m_NdasScsiLocation.SlotNo); if (!fSuccess) { DBGPRT_ERR_EX(_FT("LsBusCtlEject failed at %s.\n"), m_NdasScsiLocation.ToString()); return FALSE; } // // Now we have to wait until the ejection is complete // SetStatus(NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING); DBGPRT_INFO(_FT("Ejected successfully at slot %s.\n"), m_NdasScsiLocation.ToString()); return TRUE; }
VOID CNdasEventMonitor::Attach(CNdasLogicalDevice* pLogDevice) { ximeta::CAutoLock autolock(this); pLogDevice->AddRef(); DBGPRT_INFO(_FT("Attaching logical device %s to the monitor\n"), pLogDevice->ToString()); m_vLogDevices.push_back(pLogDevice); BOOL fSuccess = ::SetEvent(m_hLogDeviceSetChangeEvent); _ASSERT(fSuccess); }