示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}