From 2acec63b2ed75bf4b71ad257db573c4b8f9639e7 Mon Sep 17 00:00:00 2001 From: tumagonx Date: Tue, 8 Aug 2017 10:54:53 +0700 Subject: initial commit --- wireless.c | 338 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 338 insertions(+) create mode 100644 wireless.c (limited to 'wireless.c') diff --git a/wireless.c b/wireless.c new file mode 100644 index 0000000..0132824 --- /dev/null +++ b/wireless.c @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2004 Security Architects Corporation. All rights reserved. + * + * Module Name: + * + * wireless.c + * + * Abstract: + * + * This module deals with wireless cards. + * + * Author: + * + * Eugene Tsyrklevich 12-Oct-2004 + */ + + +#include + +#undef DEFINE_GUID +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name \ + = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } + +#include +#include +#include "wireless.h" +#include "pathproc.h" +#include "policy.h" + + +#ifdef ALLOC_PRAGMA +#pragma alloc_text (INIT, InitWirelessHooks) +#pragma alloc_text (PAGE, RemoveWirelessHooks) +#endif + + +PVOID WirelessNotificationEntry = NULL; + +/* removable wireless flags defined in drive.h (READONLY, etc) */ +UCHAR WirelessRemovableFlags = 0; + + +typedef struct _WORK_CONTEXT +{ + PIO_WORKITEM Item; + UNICODE_STRING SymbolicLinkName; + +} WORK_CONTEXT, *PWORK_CONTEXT; + + + +/* + * AddDrive() + * + * Description: + * . + * + * Parameters: + * pusDriveName - . + * DriveLetter - . + * + * Returns: + * Nothing. + */ + +VOID +AddDrive(PUNICODE_STRING pusDriveName, CHAR DriveLetter) +{ + PDEVICE_OBJECT pDeviceObject; + STORAGE_HOTPLUG_INFO HotplugInfo; + + + pDeviceObject = GetDriveHotplugInformation(pusDriveName, &HotplugInfo); + if (pDeviceObject == NULL) + return; + + + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("AddDrive: %c:\\ drive: %d %d %d %d %d\n", DriveLetter, HotplugInfo.Size, HotplugInfo.WirelessRemovable, HotplugInfo.WirelessHotplug, HotplugInfo.DeviceHotplug, HotplugInfo.WriteCacheEnableOverride)); + + + //XXX remove + if (HotplugInfo.WirelessRemovable == FALSE && HotplugInfo.WirelessHotplug == TRUE) + { + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("AddDrive: hotpluggable but not removable drive! %c: %S\n", DriveLetter, pusDriveName->Buffer)); + } + + if (HotplugInfo.WirelessRemovable) + { + CHAR rule[MAX_PATH]; + + + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("AddDrive: removable drive! %c: %S\n", DriveLetter, pusDriveName->Buffer)); + + + /* Create a new global policy rule */ + + if (IS_REMOVABLE_WIRELESS_DISABLED()) + { + sprintf(rule, "name match \"%c:\\*\" then %s", DriveLetter, "deny"); + + PolicyParseObjectRule(&gSecPolicy, RULE_FILE, "all", rule); + + /* no need to process other rules, this one denies everything already */ + return; + } + + if (IS_REMOVABLE_WIRELESS_READONLY()) + { + sprintf(rule, "name match \"%c:\\*\" then %s", DriveLetter, "deny"); + + PolicyParseObjectRule(&gSecPolicy, RULE_FILE, "write", rule); + } + + if (IS_REMOVABLE_WIRELESS_NOEXECUTE()) + { + sprintf(rule, "name match \"%c:\\*\" then %s", DriveLetter, "deny"); + + PolicyParseObjectRule(&gSecPolicy, RULE_FILE, "execute", rule); + } + } + + + return; +} + + + +/* + * RemoveDrive() + * + * Description: + * . + * + * Parameters: + * pusDriveName - . + * + * Returns: + * Nothing. + */ + +VOID +RemoveDrive(PUNICODE_STRING pusDriveName) +{ + PDEVICE_OBJECT pDeviceObject; + STORAGE_HOTPLUG_INFO HotplugInfo; + NTSTATUS rc; + + + pDeviceObject = GetDriveHotplugInformation(pusDriveName, &HotplugInfo); + if (pDeviceObject == NULL) + return; + +// KdPrint(("success %d %d %d %d %d\n", info.Size, info.WirelessRemovable, info.WirelessHotplug, info.DeviceHotplug, info.WriteCacheEnableOverride)); + + if (HotplugInfo.WirelessRemovable) + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("RemoveDrive: removable drive! %S\n", pusDriveName->Buffer)); + + + rc = RtlVolumeDeviceToDosName(pDeviceObject, pusDriveName); + if (NT_SUCCESS(rc)) + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("RemoveDrive: IoVolumeDeviceToDosName returned %S\n", pusDriveName->Buffer)); + + return; +} + + + +/* + * PnpWorker() + * + * Description: + * A work item routine that runs at PASSIVE_LEVEL irql. The routine is scheduled by PnpCallback + * which is not allowed to block. + * + * PnpWorker calls RemoveDrive() with a drive name setup by PnpCallback. + * + * Parameters: + * pDeviceObject - . + * Context - . + * + * Returns: + * Nothing. + */ + +VOID +PnpWorker(IN PDEVICE_OBJECT pDeviceObject, IN PVOID Context) +{ + PWORK_CONTEXT WorkContext = (PWORK_CONTEXT) Context; + + + if (WorkContext == NULL) + { + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("PnpWorker: WorkContext = NULL\n")); + return; + } + + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("PnpWorker: %S\n", WorkContext->SymbolicLinkName.Buffer)); + + + RemoveDrive(&WorkContext->SymbolicLinkName); + + + IoFreeWorkItem(WorkContext->Item); + + ExFreePoolWithTag(WorkContext, _POOL_TAG); +} + + + +/* + * PnpCallback() + * + * Description: + * Plug-and-Play callback. Gets called when a p-n-p drive/cdrom interface is modified + * (i.e. when a removable drive is added or removed from the system). + * + * Parameters: + * NotificationStructure - DEVICE_INTERFACE_CHANGE_NOTIFICATION indicating which interface changed. + * Context - the driver's device context. + * + * Returns: + * STATUS_SUCCESS. + */ + +NTSTATUS +PnpCallback(IN PVOID NotificationStructure, IN PVOID Context) +{ + PDEVICE_INTERFACE_CHANGE_NOTIFICATION Notify = (PDEVICE_INTERFACE_CHANGE_NOTIFICATION) NotificationStructure; + PDEVICE_OBJECT pDeviceObject = (PDEVICE_OBJECT) Context; + PIO_WORKITEM WorkItem; + PWORK_CONTEXT WorkContext; + + + if (IsEqualGUID((LPGUID) &Notify->Event, (LPGUID) &GUID_DEVICE_INTERFACE_REMOVAL)) + { + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("GUID_DEVICE_INTERFACE_REMOVAL %S\n", Notify->SymbolicLinkName->Buffer)); +/* + } + + + if (IsEqualGUID((LPGUID) &Notify->Event, (LPGUID) &GUID_DEVICE_INTERFACE_ARRIVAL) || + IsEqualGUID((LPGUID) &Notify->Event, (LPGUID) &GUID_DEVICE_INTERFACE_REMOVAL)) + { + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("GUID_DEVICE_INTERFACE_ARRIVAL %x %S\n", Notify->SymbolicLinkName, Notify->SymbolicLinkName->Buffer)); +*/ + + /* + * Schedule a work item to process this request. Cannot block in this callback function. + */ + + WorkItem = IoAllocateWorkItem(pDeviceObject); + + WorkContext = (PWORK_CONTEXT) ExAllocatePoolWithTag(PagedPool, + sizeof(WORK_CONTEXT) + Notify->SymbolicLinkName->Length, + _POOL_TAG); + if (!WorkContext) + { + IoFreeWorkItem(WorkItem); + return(STATUS_SUCCESS); + } + + WorkContext->SymbolicLinkName.Buffer = (PWSTR) ((PCHAR) &WorkContext->SymbolicLinkName + sizeof(UNICODE_STRING)); + WorkContext->SymbolicLinkName.MaximumLength = Notify->SymbolicLinkName->Length; + WorkContext->SymbolicLinkName.Length = 0; + + WorkContext->Item = WorkItem; + RtlCopyUnicodeString(&WorkContext->SymbolicLinkName, Notify->SymbolicLinkName); + + IoQueueWorkItem(WorkItem, PnpWorker, DelayedWorkQueue, WorkContext); + } + + + return STATUS_SUCCESS; +} + + + +/* + * InitWirelessHooks() + * + * Description: + * Process any existing wireless cards and register Plug-and-Play notifications for future drive additions/removals. + * + * NOTE: Called once during driver initialization (DriverEntry()). + * + * Parameters: + * None. + * + * Returns: + * TRUE to indicate success, FALSE if failed. + */ + +BOOLEAN +InitWirelessHooks(IN PDRIVER_OBJECT pDriverObject, IN PDEVICE_OBJECT pDeviceObject) +{ + NTSTATUS rc; + + + rc = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, + /*0,*/PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, + (LPGUID) &GUID_DEVINTERFACE_DISK, + pDriverObject, + PnpCallback, + pDeviceObject, + &WirelessNotificationEntry); + + if (! NT_SUCCESS(rc)) + { + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("InitWirelessHooks: IoRegisterPlugPlayNotification failed with status %x\n", rc)); + return FALSE; + } + + + return TRUE; +} + + + +/* + * RemoveWirelessHooks() + * + * Description: + * Unregister Plug-and-Play notifications. + * + * Parameters: + * None. + * + * Returns: + * Nothing. + */ + +VOID +RemoveWirelessHooks() +{ + if (WirelessNotificationEntry) + if (! NT_SUCCESS(IoUnregisterPlugPlayNotification(WirelessNotificationEntry))) + LOG(LOG_SS_DRIVE, LOG_PRIORITY_DEBUG, ("RemoveWirelessHooks: IoUnregisterPlugPlayNotification failed\n")); +} -- cgit v1.3