VOID CNdasIXServer::OnIXPrimaryUpdate( CLpxDatagramSocket& sock, CONST SOCKADDR_LPX* pRemoteAddr, CONST LSINFOX_PRIMARY_UPDATE* pData) { NDAS_UNITDEVICE_ID unitDeviceId = { { pData->NetDiskNode[0], pData->NetDiskNode[1], pData->NetDiskNode[2], pData->NetDiskNode[3], pData->NetDiskNode[4], pData->NetDiskNode[5] }, pData->UnitDiskNo }; CNdasUnitDevice* pUnitDevice = pGetNdasUnitDevice(unitDeviceId); if (NULL == pUnitDevice) { // // Discard non-discovered unit device // return; } NDAS_UNITDEVICE_PRIMARY_HOST_INFO hostinfo; ::CopyMemory( hostinfo.Host.Node, pData->PrimaryNode, sizeof(hostinfo.Host.Node)); hostinfo.Host.Port = NTOHS(pData->PrimaryPort); hostinfo.SWMajorVersion = pData->SWMajorVersion; hostinfo.SWMinorVersion = pData->SWMinorVersion; hostinfo.SWBuildNumber = pData->SWBuildNumber; hostinfo.NDFSCompatVersion = pData->NDFSCompatVersion; hostinfo.NDFSVersion = pData->NDFSVersion; DPNoise(_FT("LSINFOX_PRIMATE_UPDATE_MESSAGE: %02X:%02X:%02X:%02X:%02X:%02X@%d\n"), pData->NetDiskNode[0], pData->NetDiskNode[1], pData->NetDiskNode[2], pData->NetDiskNode[3], pData->NetDiskNode[4], pData->NetDiskNode[5], pData->UnitDiskNo); pUnitDevice->UpdatePrimaryHostInfo(hostinfo); return; }
NDASDI_API BOOL WINAPI NdasDiRemoveLegacyDevice( IN HWND hwndParent, IN LPCTSTR ServiceName, IN BOOL PresentOnly, OUT LPDWORD pdwRemovedDeviceCount OPTIONAL, OUT LPBOOL pbRebootRequired OPTIONAL, IN NDASDIREMOVEDEVICEERRCALLBACKPROC ErrorCallbackProc OPTIONAL, IN LPVOID Context OPTIONAL) { _ASSERTE(!IsBadStringPtr(ServiceName, LINE_LEN)); _ASSERTE(NULL == pbRebootRequired || !IsBadWritePtr(pbRebootRequired, sizeof(BOOL))); _ASSERTE(NULL == ErrorCallbackProc || !IsBadCodePtr((FARPROC)ErrorCallbackProc)); BOOL fReturn = FALSE; BOOL fSuccess = FALSE; HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData = {0}; DWORD Flags = DIGCF_ALLCLASSES; if (PresentOnly) { Flags |= DIGCF_PRESENT; } // // Create a Device Information Set with all present devices. // DeviceInfoSet = SetupDiGetClassDevs( NULL, // All Classes 0, hwndParent, Flags); // All devices present on system if (INVALID_HANDLE_VALUE == DeviceInfoSet) { goto cleanup; } if (NULL != pbRebootRequired) { *pbRebootRequired = FALSE; } // // Enumerate through all Devices. // DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (NULL != pdwRemovedDeviceCount) { *pdwRemovedDeviceCount = 0; } for (DWORD i = 0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); ++i) { DWORD DataT; LPTSTR buffer = NULL; DWORD buffersize = 0; // // We won't know the size of the HardwareID buffer until we call // this function. So call it with a null to begin with, and then // use the required buffer size to Alloc the nessicary space. // Keep calling we have success or an unknown failure. // while (TRUE) { fSuccess = SetupDiGetDeviceRegistryProperty( DeviceInfoSet, &DeviceInfoData, SPDRP_SERVICE, &DataT, (PBYTE)buffer, buffersize, &buffersize); if (fSuccess) { break; } if (ERROR_INVALID_DATA == GetLastError()) { // // May be a Legacy Device with no HardwareID. Continue. // break; } else if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { // // We need to change the buffer size. // if (buffer) { LocalFree(buffer); } buffer = (LPTSTR) LocalAlloc(LPTR,buffersize); } else { // // Unknown Failure. // if (ErrorCallbackProc) { BOOL fCont = ErrorCallbackProc( NDIRD_ERROR_GetDeviceRegistryProperty, DeviceInfoSet, &DeviceInfoData, GetLastError(), Context); if (fCont) { } fReturn = FALSE; goto cleanup; } } } // // May be a Legacy Device with no HardwareID. Continue. // if (GetLastError() == ERROR_INVALID_DATA) { continue; } // // Service Name is REG_SZ (Not MultiSZ) // LPCTSTR p = buffer; DPNoise(_T("%s\n"), p); if (0 == lstrcmpi(ServiceName,p)) { DPNoise(_T("\n>>> %s <<<\n"), p); // // Worker function to remove device. // fSuccess = SetupDiCallClassInstaller( DIF_REMOVE, DeviceInfoSet, &DeviceInfoData); if (!fSuccess && ErrorCallbackProc) { BOOL fCont = ErrorCallbackProc( NDIRD_ERROR_CallRemoveToClassInstaller, DeviceInfoSet, &DeviceInfoData, GetLastError(), Context); if (buffer) { LocalFree(buffer); } fReturn = FALSE; goto cleanup; } // // Get the installation param // if (NULL != pbRebootRequired) { SP_DEVINSTALL_PARAMS diParams = {0}; diParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); fSuccess = SetupDiGetDeviceInstallParams( DeviceInfoSet, &DeviceInfoData, &diParams); _ASSERTE(fSuccess); *pbRebootRequired |= (diParams.Flags & DI_NEEDREBOOT) || (diParams.Flags & DI_NEEDRESTART); } if (NULL != pdwRemovedDeviceCount) { ++(*pdwRemovedDeviceCount); } break; } if (buffer) { LocalFree(buffer); } } if ((NO_ERROR != GetLastError()) && (ERROR_NO_MORE_ITEMS != GetLastError())) { fReturn = FALSE; } else { fReturn = TRUE; } // // Cleanup. // cleanup: DWORD err = GetLastError(); if (INVALID_HANDLE_VALUE != DeviceInfoSet) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); } SetLastError(err); return fReturn; }
VOID CNdasIXServer::OnIXUsageRequest( CLpxDatagramSocket& sock, CONST SOCKADDR_LPX* pRemoteAddr, CONST LSINFOX_NDASDEV_USAGE_REQUEST* pData) { NDAS_UNITDEVICE_ID unitDeviceId = { { pData->NetDiskNode[0], pData->NetDiskNode[1], pData->NetDiskNode[2], pData->NetDiskNode[3], pData->NetDiskNode[4], pData->NetDiskNode[5] }, pData->UnitDiskNo }; DPNoise(_FT("LSINFOX_PRIMARY_USAGE_MESSAGE: %02X:%02X:%02X:%02X:%02X:%02X@%d\n"), pData->NetDiskNode[0], pData->NetDiskNode[1], pData->NetDiskNode[2], pData->NetDiskNode[3], pData->NetDiskNode[4], pData->NetDiskNode[5], pData->UnitDiskNo); CNdasLogicalDevice* pLogDevice = pGetNdasLogicalDevice(unitDeviceId); if (NULL == pLogDevice) { // Discard message return; } switch (pLogDevice->GetStatus()) { case NDAS_LOGICALDEVICE_STATUS_MOUNTED: case NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING: case NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING: break; default: // // Otherwise, discard message // return; } ACCESS_MASK mountedAcces = pLogDevice->GetMountedAccess(); CONST DWORD cbPacket = sizeof(LSINFOX_HEADER) + sizeof(LSINFOX_NDASDEV_USAGE_REPLY) + MAX_HOSTNAME_LEN * sizeof(WCHAR); BYTE pbPacket[cbPacket] = {0}; PLSINFOX_HEADER pHeader = reinterpret_cast<PLSINFOX_HEADER>(pbPacket); PLSINFOX_NDASDEV_USAGE_REPLY pUsageReply = reinterpret_cast<PLSINFOX_NDASDEV_USAGE_REPLY>( pbPacket + sizeof(LSINFOX_HEADER)); // // Header // CONST BYTE NdasIxProtocolName[] = INFOX_DATAGRAM_PROTOCOL; ::CopyMemory( pHeader->Protocol, NdasIxProtocolName, sizeof(NdasIxProtocolName)); pHeader->LSInfoXMajorVersion = INFOX_DATAGRAM_MAJVER; pHeader->LSInfoXMinorVersion = INFOX_DATAGRAM_MINVER; pHeader->OsMajorType = OSTYPE_WINDOWS; DWORD dwOSMajorVersion, dwOSMinorVersion; pGetOSVersion(&dwOSMajorVersion, &dwOSMinorVersion); USHORT usLfsOsMinorType = pInfoXGetOSType(dwOSMajorVersion, dwOSMinorVersion); pHeader->OsMinorType = usLfsOsMinorType; pHeader->Type = LSINFOX_PRIMARY_UPDATE_MESSAGE | LSINFOX_TYPE_REPLY; pHeader->MessageSize = cbPacket; // // Body // LPX_ADDRESS localLpxAddress = sock.GetBoundAddr()->LpxAddress; pUsageReply->HostLanAddr.AddressType = LSNODE_ADDRTYPE_ETHER; pUsageReply->HostLanAddr.AddressLen = LPXADDR_NODE_LENGTH; ::CopyMemory( pUsageReply->HostLanAddr.Address, localLpxAddress.Node, LPXADDR_NODE_LENGTH); WCHAR wszHostName[MAX_HOSTNAME_LEN] = {0}; USHORT hostNameType = LSNODENAME_DNSFULLYQ; DWORD cchHostName = MAX_HOSTNAME_LEN; BOOL fSuccess = ::GetComputerNameExW( ComputerNameDnsFullyQualified, wszHostName, &cchHostName); if (!fSuccess) { hostNameType = LSNODENAME_NETBOIS; cchHostName = MAX_HOSTNAME_LEN; fSuccess = ::GetComputerNameExW( ComputerNameNetBIOS, wszHostName, &cchHostName); } if (!fSuccess) { hostNameType = LSNODENAME_UNKNOWN; cchHostName = 0; } pUsageReply->HostNameType = hostNameType; pUsageReply->HostNameLength = cchHostName; ::CopyMemory( pUsageReply->HostName, wszHostName, cchHostName * sizeof(WCHAR)); // // LPX Address.Node is an adapter address. // const DWORD cbAdapterAddress = 6; BYTE pAdapterAddress[cbAdapterAddress] = {0}; ::CopyMemory(pAdapterAddress, localLpxAddress.Node, 6); DWORD cbIpAddress = 14; // TODO: why is this 14? BYTE pPrimaryIpAddress[14] = {0}; fSuccess = pGetAdapterPrimaryIpAddress( cbAdapterAddress, pAdapterAddress, &cbIpAddress, pPrimaryIpAddress); fSuccess = FALSE; if (!fSuccess) { DBGPRT_WARN_EX(_FT("Failed to get primary ip address of %s: "), CSockLpxAddr(sock.GetBoundAddr()).ToString()); pUsageReply->HostWanAddr.AddressLen = 0; pUsageReply->HostWanAddr.AddressType = LSNODE_ADDRTYPE_IP; ::ZeroMemory(pUsageReply->HostWanAddr.Address, LSNODE_ADDR_LENGTH); } else { pUsageReply->HostWanAddr.AddressLen = (USHORT) cbIpAddress; pUsageReply->HostWanAddr.AddressType = LSNODE_ADDRTYPE_IP; _ASSERTE(cbIpAddress <= LSNODE_ADDR_LENGTH); ::CopyMemory( pUsageReply->HostWanAddr.Address, pPrimaryIpAddress, cbIpAddress); } // // Software Versions, status, etc // if (mountedAcces & GENERIC_READ) { pUsageReply->AccessRight |= LSSESSION_ACCESS_READ; } if (mountedAcces & GENERIC_WRITE) { pUsageReply->AccessRight |= LSSESSION_ACCESS_WRITE; } pUsageReply->NetDiskPort = NDAS_DEVICE_LPX_PORT; pUsageReply->UnitDiskNo = unitDeviceId.UnitNo; pUsageReply->UsageID = 0; pUsageReply->SWMajorVersion = NDASIX_VERSION_MAJOR; pUsageReply->SWMinorVersion = NDASIX_VERSION_MINOR; pUsageReply->SWBuildNumber = NDASIX_VERSION_BUILD; pUsageReply->NDFSCompatVersion = m_NDFSVersion.wMajor; pUsageReply->NDFSVersion = m_NDFSVersion.wMinor; DWORD cbSent = 0; fSuccess = sock.SendToSync(pRemoteAddr, cbPacket, pbPacket, 0, &cbSent); if (!fSuccess) { DBGPRT_ERR_EX(_FT("Failed to send a reply (%d bytes): "), cbPacket); return; } return; }