Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dockhwp.c File Reference

#include "iop.h"
#include "..\config\cmp.h"
#include <string.h>
#include <profiles.h>
#include <wdmguid.h>

Go to the source code of this file.

Classes

struct  PROFILE_WORK_ITEM

Defines

#define ASSERT_SEMA_NOT_SIGNALLED(SemaphoreObject)

Typedefs

typedef * PPROFILE_WORK_ITEM

Functions

NTSTATUS IopExecuteHardwareProfileChange (IN HARDWARE_PROFILE_BUS_TYPE Bus, IN PWCHAR *ProfileSerialNumbers, IN ULONG SerialNumbersCount, OUT PHANDLE NewProfile, OUT PBOOLEAN ProfileChanged)
NTSTATUS IopUpdateHardwareProfile (OUT PBOOLEAN ProfileChanged)
VOID IopHardwareProfileSendCommit (VOID)
VOID IopHardwareProfileSendCancel (VOID)
VOID IopHardwareProfileBeginTransition (IN BOOLEAN SubsumeExistingDeparture)
VOID IopHardwareProfileMarkDock (PDEVICE_NODE DeviceNode, PROFILE_STATUS ChangeInPresence)
NTSTATUS IopHardwareProfileQueryChange (IN BOOLEAN SubsumingExistingDeparture, IN PROFILE_NOTIFICATION_TIME InPnpEvent, OUT PPNP_VETO_TYPE VetoType, OUT PUNICODE_STRING VetoName OPTIONAL)
VOID IopHardwareProfileCommitStartedDock (IN PDEVICE_NODE DeviceNode)
VOID IopHardwareProfileCommitRemovedDock (IN PDEVICE_NODE DeviceNode)
VOID IopHardwareProfileCancelRemovedDock (IN PDEVICE_NODE DeviceNode)
VOID IopHardwareProfileCancelTransition (VOID)
VOID IopHardwareProfileSetMarkedDocksEjected (VOID)
NTSTATUS IopExecuteHwpDefaultSelect (IN PCM_HARDWARE_PROFILE_LIST ProfileList, OUT PULONG ProfileIndexToUse, IN PVOID Context)

Variables

LIST_ENTRY IopDockDeviceListHead
ULONG IopDockDeviceCount
FAST_MUTEX IopDockDeviceListLock
KSEMAPHORE IopProfileChangeSemaphore
BOOLEAN IopProfileChangeCancelRequired
LONG IopDocksInTransition


Define Documentation

#define ASSERT_SEMA_NOT_SIGNALLED SemaphoreObject   ) 
 

Definition at line 35 of file dockhwp.c.

Referenced by IopHardwareProfileBeginTransition(), IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileCommitStartedDock(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopHardwareProfileSendCancel(), IopHardwareProfileSendCommit(), and IopHardwareProfileSetMarkedDocksEjected().


Typedef Documentation

typedef * PPROFILE_WORK_ITEM
 


Function Documentation

NTSTATUS IopExecuteHardwareProfileChange IN HARDWARE_PROFILE_BUS_TYPE  Bus,
IN PWCHAR *  ProfileSerialNumbers,
IN ULONG  SerialNumbersCount,
OUT PHANDLE  NewProfile,
OUT PBOOLEAN  ProfileChanged
 

Definition at line 1028 of file dockhwp.c.

References ASSERT, Buffer, CmSetAcpiHwProfile(), _PROFILE_ACPI_DOCKING_STATE::DockingState, ExAllocatePool, ExFreePool(), FALSE, HardwareProfileBusTypeACPI, HW_PROFILE_DOCKSTATE_DOCKED, HW_PROFILE_DOCKSTATE_UNDOCKED, IopExecuteHwpDefaultSelect(), L, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, RtlCompareUnicodeString(), RtlInitUnicodeString(), _PROFILE_ACPI_DOCKING_STATE::SerialLength, _PROFILE_ACPI_DOCKING_STATE::SerialNumber, and USHORT.

Referenced by IopUpdateHardwareProfile().

01038 : 01039 A docking event has occured and now, given a list of Profile Serial Numbers 01040 that describe the new docking state: 01041 Transition to the given docking state. 01042 Set the Current Hardware Profile to based on the new state. 01043 (Possibly Prompt the user if there is ambiguity) 01044 Send Removes to those devices that are turned off in this profile, 01045 01046 Arguments: 01047 Bus - This is the bus that is supplying the hardware profile change 01048 (currently only HardwareProfileBusTypeAcpi is supported). 01049 01050 ProfileSerialNumbers - A list of serial numbers (a list of null terminated 01051 UCHAR lists) representing this new docking state. These can be listed in 01052 any order, and form a complete representation of the new docking state 01053 caused by a docking even on the given bus. A Serial Number string of "\0" 01054 represents an "undocked state" and should not be listed with any other 01055 strings. This list need not be sorted. 01056 01057 SerialNumbersCount - The number of serial numbers listed. 01058 01059 NewProfile - a handle to the registry key representing the new hardware 01060 profile (IE \CCS\HardwareProfiles\Current".) 01061 01062 ProfileChanged - set to TRUE if new current profile (as a result of this 01063 docking event, is different that then old current profile. 01064 01065 --*/ 01066 { 01067 NTSTATUS status = STATUS_SUCCESS; 01068 ULONG len; 01069 ULONG tmplen; 01070 ULONG i, j; 01071 PWCHAR tmpStr; 01072 UNICODE_STRING tmpUStr; 01073 PUNICODE_STRING sortedSerials = NULL; 01074 01075 PPROFILE_ACPI_DOCKING_STATE dockState = NULL; 01076 01077 PIDBGMSG( 01078 PIDBG_HWPROFILE, 01079 ("Execute Profile (BusType %x), (SerialNumCount %x)\n", Bus, SerialNumbersCount) 01080 ) ; 01081 01082 // 01083 // Sort the list of serial numbers 01084 // 01085 len = sizeof (UNICODE_STRING) * SerialNumbersCount; 01086 sortedSerials = ExAllocatePool (NonPagedPool, len); 01087 if (NULL == sortedSerials) { 01088 status = STATUS_INSUFFICIENT_RESOURCES; 01089 goto Clean; 01090 } 01091 for (i = 0; i < SerialNumbersCount; i++) { 01092 RtlInitUnicodeString (&sortedSerials[i], ProfileSerialNumbers[i]); 01093 } 01094 // 01095 // I do not anticipate getting more than a few serial numbers, and I am 01096 // just lasy enough to write this comment and use a buble sort. 01097 // 01098 for (i = 0; i < SerialNumbersCount; i++) { 01099 for (j = 0; j < SerialNumbersCount - 1; j++) { 01100 if (0 < RtlCompareUnicodeString (&sortedSerials[j], 01101 &sortedSerials[j+1], 01102 FALSE)) { 01103 tmpUStr = sortedSerials[j]; 01104 sortedSerials[j] = sortedSerials[j+1]; 01105 sortedSerials[j+1] = tmpUStr; 01106 } 01107 } 01108 } 01109 01110 // 01111 // Construct the DockState ID 01112 // 01113 len = 0; 01114 for (i = 0; i < SerialNumbersCount; i++) { 01115 len += sortedSerials[i].Length; 01116 } 01117 len += sizeof (WCHAR); // NULL termination; 01118 01119 dockState = (PPROFILE_ACPI_DOCKING_STATE) 01120 ExAllocatePool (NonPagedPool, 01121 len + sizeof (PROFILE_ACPI_DOCKING_STATE)); 01122 // BUGBUG wasted WCHAR here. Oh well. 01123 01124 if (NULL == dockState) { 01125 status = STATUS_INSUFFICIENT_RESOURCES; 01126 goto Clean; 01127 } 01128 for (i = 0, tmpStr = dockState->SerialNumber, tmplen = 0; 01129 i < SerialNumbersCount; 01130 i++) { 01131 01132 tmplen = sortedSerials[i].Length; 01133 ASSERT (tmplen <= len - ((PCHAR)tmpStr - (PCHAR)dockState->SerialNumber)); 01134 01135 RtlCopyMemory (tmpStr, sortedSerials[i].Buffer, tmplen); 01136 (PCHAR) tmpStr += tmplen; 01137 } 01138 01139 *(tmpStr++) = L'\0'; 01140 01141 ASSERT (len == (ULONG) ((PCHAR) tmpStr - (PCHAR) dockState->SerialNumber)); 01142 dockState->SerialLength = (USHORT) len; 01143 01144 if ((SerialNumbersCount > 1) || (L'\0' != dockState->SerialNumber[0])) { 01145 dockState->DockingState = HW_PROFILE_DOCKSTATE_DOCKED; 01146 } else { 01147 dockState->DockingState = HW_PROFILE_DOCKSTATE_UNDOCKED; 01148 } 01149 01150 01151 // 01152 // Set the new Profile 01153 // 01154 switch (Bus) { 01155 case HardwareProfileBusTypeACPI: 01156 01157 status = CmSetAcpiHwProfile (dockState, 01158 IopExecuteHwpDefaultSelect, 01159 NULL, 01160 NewProfile, 01161 ProfileChanged); 01162 01163 ASSERT(NT_SUCCESS(status) || (!(*ProfileChanged))) ; 01164 break; 01165 01166 default: 01167 *ProfileChanged = FALSE ; 01168 status = STATUS_NOT_SUPPORTED; 01169 goto Clean; 01170 } 01171 01172 Clean: 01173 if (NULL != sortedSerials) { 01174 ExFreePool (sortedSerials); 01175 } 01176 if (NULL != dockState) { 01177 ExFreePool (dockState); 01178 } 01179 01180 return status; 01181 }

NTSTATUS IopExecuteHwpDefaultSelect IN PCM_HARDWARE_PROFILE_LIST  ProfileList,
OUT PULONG  ProfileIndexToUse,
IN PVOID  Context
 

Definition at line 1014 of file dockhwp.c.

Referenced by IopExecuteHardwareProfileChange().

01019 { 01020 UNREFERENCED_PARAMETER (Context); 01021 01022 * ProfileIndexToUse = 0; 01023 01024 return STATUS_SUCCESS; 01025 }

VOID IopHardwareProfileBeginTransition IN BOOLEAN  SubsumeExistingDeparture  ) 
 

Definition at line 103 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, Executive, FALSE, IopDocksInTransition, IopProfileChangeSemaphore, KernelMode, KeWaitForSingleObject(), NTSTATUS(), and NULL.

Referenced by IopStartDevice().

00108 : 00109 00110 This routine must be called before any dock devnodes can be marked for 00111 transition (ie arriving or departing). After calling this function, 00112 IopHardwareProfileMarkDock should be called for each dock that is appearing 00113 or disappearing. 00114 00115 Functionally, this code acquires the profile change semaphore. Future 00116 changes in the life of the added dock devnodes cause it to be released. 00117 00118 Arguments: 00119 00120 SubsumeExistingDeparture - Set if we are ejecting the parent of a 00121 device that is still in the process of 00122 ejecting... 00123 00124 Return Value: 00125 00126 None. 00127 00128 --*/ 00129 { 00130 NTSTATUS status ; 00131 00132 if (SubsumeExistingDeparture) { 00133 00134 // 00135 // We will already have queried in this case. Also, enumeration is 00136 // locked right now, so the appropriate devices found cannot disappear. 00137 // Assert everything is consistant. 00138 // 00139 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00140 ASSERT(IopDocksInTransition != 0) ; 00141 return ; 00142 } 00143 00144 // 00145 // Take the profile change semaphore. We do this whenever a dock is 00146 // in our list, even if no query is going to occur. 00147 // 00148 status = KeWaitForSingleObject( 00149 &IopProfileChangeSemaphore, 00150 Executive, 00151 KernelMode, 00152 FALSE, 00153 NULL 00154 ); 00155 00156 ASSERT(status == STATUS_SUCCESS) ; 00157 }

VOID IopHardwareProfileCancelRemovedDock IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 572 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_EJECTIRP_COMPLETED, DOCK_QUIESCENT, FALSE, IO_NO_INCREMENT, IopDockDeviceListLock, IopDocksInTransition, IopHardwareProfileSendCancel(), IopHardwareProfileSendCommit(), IopProcessNewProfile(), IopProfileChangeCancelRequired, IopProfileChangeSemaphore, IopUpdateHardwareProfile(), KeReleaseSemaphore(), NT_SUCCESS, and NTSTATUS().

Referenced by IopEnumerateDevice().

00577 : 00578 00579 This routine is called when a dock that was marked to disappear didn't (ie, 00580 after the eject, the dock device still enumerated). We remove it from the 00581 transition list and complete/cancel the HW profile change as appropriate. 00582 See IopHardwareProfileSetMarkedDocksEjected. 00583 00584 Arguments: 00585 00586 DeviceNode - Supplies a pointer to a device node which will be started and 00587 enumerated. 00588 00589 Return Value: 00590 00591 None. 00592 00593 --*/ 00594 { 00595 NTSTATUS status; 00596 BOOLEAN profileChanged ; 00597 LONG remainingDockCount ; 00598 00599 // 00600 // Acquire the lock on the list of dock devices 00601 // 00602 ExAcquireFastMutex(&IopDockDeviceListLock); 00603 00604 // 00605 // Since we are about to remove this dock device from the list of 00606 // all dock devices present, the list should not be empty. 00607 // 00608 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00609 ASSERT(DeviceNode->DockInfo.DockStatus == DOCK_EJECTIRP_COMPLETED) ; 00610 ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ; 00611 00612 DeviceNode->DockInfo.DockStatus = DOCK_QUIESCENT ; 00613 remainingDockCount = InterlockedDecrement(&IopDocksInTransition) ; 00614 ASSERT(remainingDockCount >= 0) ; 00615 00616 // 00617 // Release the lock on the list of dock devices 00618 // 00619 ExReleaseFastMutex(&IopDockDeviceListLock); 00620 00621 if (remainingDockCount) { 00622 00623 return ; 00624 } 00625 00626 // 00627 // Update the current Hardware Profile after removing this device. 00628 // 00629 status = IopUpdateHardwareProfile(&profileChanged); 00630 00631 if (!NT_SUCCESS(status)) { 00632 00633 // 00634 // So we're there physically, but not mentally? Too bad, where broadcasting 00635 // change either way. 00636 // 00637 PIDBGMSG( 00638 PIDBG_HWPROFILE, 00639 ("IopUpdateHardwareProfile failed with status == %lx\n", status) 00640 ) ; 00641 ASSERT(NT_SUCCESS(status)) ; 00642 } 00643 00644 if (NT_SUCCESS(status) && profileChanged) { 00645 00646 IopHardwareProfileSendCommit() ; 00647 IopProcessNewProfile(); 00648 00649 } else { 00650 00651 ASSERT(IopProfileChangeCancelRequired) ; 00652 IopHardwareProfileSendCancel() ; 00653 } 00654 00655 KeReleaseSemaphore( 00656 &IopProfileChangeSemaphore, 00657 IO_NO_INCREMENT, 00658 1, 00659 FALSE 00660 ); 00661 00662 return ; 00663 }

VOID IopHardwareProfileCancelTransition VOID   ) 
 

Definition at line 666 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_EJECTIRP_COMPLETED, DOCK_NOTDOCKDEVICE, DOCK_QUIESCENT, _DEVICE_NODE::DockInfo, FALSE, IO_NO_INCREMENT, IopDockDeviceListHead, IopDockDeviceListLock, IopDocksInTransition, IopHardwareProfileSendCancel(), IopProfileChangeCancelRequired, IopProfileChangeSemaphore, and KeReleaseSemaphore().

Referenced by IopStartDevice().

00671 : 00672 00673 This routine unmarks any marked devnodes (ie, sets them to no change, 00674 appearing or disappearing), and sends the CancelQueryProfileChange as 00675 appropriate. Once called, other profile changes can occur. 00676 00677 Arguments: 00678 00679 None. 00680 00681 Return Value: 00682 00683 Nodda. 00684 00685 --*/ 00686 { 00687 PLIST_ENTRY listEntry; 00688 PDEVICE_NODE devNode; 00689 00690 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00691 00692 // 00693 // Acquire the lock on the list of dock devices 00694 // 00695 ExAcquireFastMutex(&IopDockDeviceListLock); 00696 00697 for (listEntry = IopDockDeviceListHead.Flink; 00698 listEntry != &(IopDockDeviceListHead); 00699 listEntry = listEntry->Flink ) { 00700 00701 devNode = CONTAINING_RECORD(listEntry, 00702 DEVICE_NODE, 00703 DockInfo.ListEntry); 00704 00705 ASSERT((devNode->DockInfo.DockStatus != DOCK_NOTDOCKDEVICE)&& 00706 (devNode->DockInfo.DockStatus != DOCK_EJECTIRP_COMPLETED)) ; 00707 if (devNode->DockInfo.DockStatus != DOCK_QUIESCENT) { 00708 00709 InterlockedDecrement(&IopDocksInTransition) ; 00710 devNode->DockInfo.DockStatus = DOCK_QUIESCENT ; 00711 } 00712 } 00713 00714 ASSERT(!IopDocksInTransition) ; 00715 00716 // 00717 // Release the lock on the list of dock devices 00718 // 00719 ExReleaseFastMutex(&IopDockDeviceListLock); 00720 00721 if (IopProfileChangeCancelRequired) { 00722 00723 IopHardwareProfileSendCancel() ; 00724 } 00725 00726 // 00727 // No need to broadcast the cancels here, as IopQueryHardwareProfileChange 00728 // will have taken care of the cancels for us. 00729 // 00730 KeReleaseSemaphore( 00731 &IopProfileChangeSemaphore, 00732 IO_NO_INCREMENT, 00733 1, 00734 FALSE 00735 ); 00736 }

VOID IopHardwareProfileCommitRemovedDock IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 465 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_DEPARTING, DOCK_EJECTIRP_COMPLETED, DOCK_QUIESCENT, ExFreePool(), FALSE, IO_NO_INCREMENT, IopDockDeviceCount, IopDockDeviceListLock, IopDocksInTransition, IopHardwareProfileSendCancel(), IopHardwareProfileSendCommit(), IopProcessNewProfile(), IopProfileChangeCancelRequired, IopProfileChangeSemaphore, IopUpdateHardwareProfile(), KeReleaseSemaphore(), NT_SUCCESS, NTSTATUS(), and NULL.

Referenced by IopDeleteLockedDeviceNode().

00470 : 00471 00472 This routine removes the specified device from the list of current dock 00473 devices and requests a Hardware Profile change. 00474 00475 Arguments: 00476 00477 DeviceNode - Supplies a pointer to a device node which has been listed as 00478 missing in a previous enumeration, has had the final remove IRP 00479 sent to it, and is about to be deleted. 00480 00481 Return Value: 00482 00483 None. 00484 00485 --*/ 00486 { 00487 NTSTATUS status; 00488 BOOLEAN profileChanged ; 00489 LONG remainingDockCount ; 00490 00491 // 00492 // Acquire the lock on the list of dock devices 00493 // 00494 ExAcquireFastMutex(&IopDockDeviceListLock); 00495 00496 // 00497 // Since we are about to remove this dock device from the list of 00498 // all dock devices present, the list should not be empty. 00499 // 00500 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00501 ASSERT((DeviceNode->DockInfo.DockStatus == DOCK_DEPARTING)|| 00502 (DeviceNode->DockInfo.DockStatus == DOCK_EJECTIRP_COMPLETED)) ; 00503 ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ; 00504 00505 // 00506 // Remove the current devnode from the list of docks 00507 // 00508 RemoveEntryList(&DeviceNode->DockInfo.ListEntry); 00509 InitializeListHead(&DeviceNode->DockInfo.ListEntry); 00510 if (DeviceNode->DockInfo.SerialNumber) { 00511 00512 ExFreePool(DeviceNode->DockInfo.SerialNumber); 00513 DeviceNode->DockInfo.SerialNumber = NULL; 00514 } 00515 IopDockDeviceCount--; 00516 00517 DeviceNode->DockInfo.DockStatus = DOCK_QUIESCENT ; 00518 remainingDockCount = InterlockedDecrement(&IopDocksInTransition) ; 00519 ASSERT(remainingDockCount >= 0) ; 00520 00521 // 00522 // Release the lock on the list of dock devices 00523 // 00524 ExReleaseFastMutex(&IopDockDeviceListLock); 00525 00526 if (remainingDockCount) { 00527 00528 return ; 00529 } 00530 00531 // 00532 // Update the current Hardware Profile after removing this device. 00533 // 00534 status = IopUpdateHardwareProfile(&profileChanged); 00535 00536 if (!NT_SUCCESS(status)) { 00537 00538 // 00539 // So we're there physically, but not mentally? Too bad, where broadcasting 00540 // change either way. 00541 // 00542 PIDBGMSG( 00543 PIDBG_HWPROFILE, 00544 ("IopUpdateHardwareProfile failed with status == %lx\n", status) 00545 ) ; 00546 00547 ASSERT(NT_SUCCESS(status)) ; 00548 } 00549 00550 if (NT_SUCCESS(status) && profileChanged) { 00551 00552 IopHardwareProfileSendCommit() ; 00553 IopProcessNewProfile(); 00554 00555 } else { 00556 00557 ASSERT(IopProfileChangeCancelRequired) ; 00558 IopHardwareProfileSendCancel() ; 00559 } 00560 00561 KeReleaseSemaphore( 00562 &IopProfileChangeSemaphore, 00563 IO_NO_INCREMENT, 00564 1, 00565 FALSE 00566 ); 00567 00568 return ; 00569 }

VOID IopHardwareProfileCommitStartedDock IN PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 370 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_ARRIVING, DOCK_QUIESCENT, FALSE, IO_NO_INCREMENT, IopDocksInTransition, IopHardwareProfileSendCancel(), IopHardwareProfileSendCommit(), IopProcessNewProfile(), IopProfileChangeCancelRequired, IopProfileChangeSemaphore, IopQueryDeviceSerialNumber(), IopUpdateHardwareProfile(), KeReleaseSemaphore(), NT_SUCCESS, NTSTATUS(), and NULL.

Referenced by IopStartDevice().

00375 : 00376 00377 This routine adds the specified device from the list of current dock 00378 devices and requests a Hardware Profile change. 00379 00380 Arguments: 00381 00382 DeviceNode - Supplies a pointer to a device node which will be started and 00383 enumerated. 00384 00385 Return Value: 00386 00387 None. 00388 00389 --*/ 00390 { 00391 NTSTATUS status; 00392 PDEVICE_OBJECT deviceObject; 00393 PWCHAR deviceSerialNumber; 00394 BOOLEAN profileChanged = FALSE ; 00395 00396 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00397 ASSERT(DeviceNode->DockInfo.DockStatus == DOCK_ARRIVING) ; 00398 ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ; 00399 00400 DeviceNode->DockInfo.DockStatus = DOCK_QUIESCENT ; 00401 InterlockedDecrement(&IopDocksInTransition) ; 00402 00403 // 00404 // We only add one dock at a time. So this should have been the last! 00405 // 00406 ASSERT(!IopDocksInTransition) ; 00407 00408 // 00409 // Retrieve the Serial Number from this dock device 00410 // 00411 if (DeviceNode->DockInfo.SerialNumber == NULL) { 00412 00413 deviceObject = DeviceNode->PhysicalDeviceObject; 00414 00415 status = IopQueryDeviceSerialNumber(deviceObject, 00416 &deviceSerialNumber); 00417 00418 DeviceNode->DockInfo.SerialNumber = deviceSerialNumber; 00419 00420 // 00421 // Update the current Hardware Profile after successfully starting this 00422 // device. This routine does two things for us: 00423 // 1) It determines whether the profile actually changed and updates 00424 // the global flag IopProfileChangeOccured appropriately. 00425 // 2) If the profile changed, this routine updates the registry, but 00426 // does *not* broadcast the profile change around. 00427 // 00428 status = IopUpdateHardwareProfile(&profileChanged); 00429 if (!NT_SUCCESS(status)) { 00430 00431 PIDBGMSG( 00432 PIDBG_HWPROFILE, 00433 ("IopUpdateHardwareProfile failed with status == %lx\n", status) 00434 ) ; 00435 } 00436 00437 } else { 00438 // 00439 // Couldn't get Serial Number for this dock device, or serial number was NULL 00440 // 00441 status = STATUS_UNSUCCESSFUL; 00442 } 00443 00444 if (NT_SUCCESS(status) && profileChanged) { 00445 00446 IopHardwareProfileSendCommit() ; 00447 IopProcessNewProfile(); 00448 00449 } else if (IopProfileChangeCancelRequired) { 00450 00451 IopHardwareProfileSendCancel() ; 00452 } 00453 00454 KeReleaseSemaphore( 00455 &IopProfileChangeSemaphore, 00456 IO_NO_INCREMENT, 00457 1, 00458 FALSE 00459 ); 00460 00461 return ; 00462 }

VOID IopHardwareProfileMarkDock PDEVICE_NODE  DeviceNode,
PROFILE_STATUS  ChangeInPresence
 

Definition at line 160 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_ARRIVING, DOCK_DEPARTING, DOCK_QUIESCENT, _DEVICE_NODE::DockInfo, ExFreePool(), IopDockDeviceCount, IopDockDeviceListHead, IopDockDeviceListLock, IopDocksInTransition, IopProfileChangeSemaphore, IopQueryDeviceSerialNumber(), NT_SUCCESS, NTSTATUS(), NULL, and _DEVICE_NODE::PhysicalDeviceObject.

Referenced by IopStartDevice().

00166 : 00167 00168 This routine is called to mark a dock as "in transition", ie it is either 00169 disappearing or appearing, the results of which determine our final 00170 hardware profile state. After all the docks that are transitioning have 00171 been passed into this function, IopHardwareProfileQueryChange is called. 00172 00173 Arguments: 00174 00175 DeviceNode - The dock devnode that is appearing or disappearing 00176 ChangeInPresence - Either DOCK_DEPARTING or DOCK_ARRIVING 00177 00178 Return Value: 00179 00180 Nope. 00181 00182 --*/ 00183 { 00184 PWCHAR deviceSerialNumber; 00185 PDEVICE_OBJECT deviceObject; 00186 NTSTATUS status; 00187 00188 // 00189 // Verify we are under semaphore, we aren't marking the dock twice, and 00190 // our parameters are sensable. 00191 // 00192 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00193 ASSERT(DeviceNode->DockInfo.DockStatus == DOCK_QUIESCENT) ; 00194 ASSERT((ChangeInPresence == DOCK_DEPARTING)|| 00195 (ChangeInPresence == DOCK_ARRIVING)) ; 00196 00197 if (ChangeInPresence == DOCK_ARRIVING) { 00198 00199 // 00200 // First, ensure this dock is a member of the dock list. 00201 // ADRIAO BUGBUG 11/12/98 - 00202 // We should move this into IopProcessNewDeviceNode. 00203 // 00204 if (IsListEmpty(&DeviceNode->DockInfo.ListEntry)) { 00205 00206 // 00207 // Acquire the lock on the list of dock devices 00208 // 00209 ExAcquireFastMutex(&IopDockDeviceListLock); 00210 00211 // 00212 // Add this element to the head of the list 00213 // 00214 InsertHeadList(&IopDockDeviceListHead, 00215 &DeviceNode->DockInfo.ListEntry); 00216 IopDockDeviceCount++; 00217 00218 // 00219 // Release the lock on the list of dock devices 00220 // 00221 ExReleaseFastMutex(&IopDockDeviceListLock); 00222 } 00223 00224 // 00225 // Retrieve the Serial Number from this dock device. We do this just 00226 // to test the BIOS today. Later we will be acquiring the information 00227 // to determine the profile we are *about* to enter. 00228 // 00229 deviceObject = DeviceNode->PhysicalDeviceObject; 00230 status = IopQueryDeviceSerialNumber(deviceObject, 00231 &deviceSerialNumber); 00232 00233 if (NT_SUCCESS(status) && (deviceSerialNumber != NULL)) { 00234 00235 ExFreePool(deviceSerialNumber) ; 00236 } 00237 00238 } else { 00239 00240 // 00241 // DOCK_DEPARTING case, we must be a member of the dock list... 00242 // 00243 ASSERT(!IsListEmpty(&DeviceNode->DockInfo.ListEntry)) ; 00244 } 00245 00246 InterlockedIncrement(&IopDocksInTransition) ; 00247 DeviceNode->DockInfo.DockStatus = ChangeInPresence ; 00248 }

NTSTATUS IopHardwareProfileQueryChange IN BOOLEAN  SubsumingExistingDeparture,
IN PROFILE_NOTIFICATION_TIME  InPnpEvent,
OUT PPNP_VETO_TYPE  VetoType,
OUT PUNICODE_STRING VetoName  OPTIONAL
 

Definition at line 251 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_ARRIVING, DOCK_EJECTIRP_COMPLETED, DOCK_NOTDOCKDEVICE, _DEVICE_NODE::DockInfo, FALSE, IopDockDeviceListHead, IopDockDeviceListLock, IopDocksInTransition, IopProfileChangeCancelRequired, IopProfileChangeSemaphore, IopRequestHwProfileChangeNotification(), NT_SUCCESS, NTSTATUS(), and TRUE.

Referenced by IopStartDevice().

00259 : 00260 00261 This function queries drivers to see if it is OK to exit the current 00262 hardware profile and enter next one (as determined by which docks have 00263 been marked). One of three functions should be used subsequently to this 00264 call: 00265 IopHardwareProfileCommitStartedDock (call when a dock has successfully 00266 started) 00267 IopHardwareProfileCommitRemovedDock (call when a dock is no longer 00268 present in the system) 00269 IopHardwareProfileCancelTransition (call to abort a transition, say 00270 if a dock failed to start or a 00271 query returned failure for eject) 00272 00273 Arguments: 00274 00275 InPnpEvent - This argument indicates whether an operation is being done 00276 within the context of another PnpEvent or not. If not, we 00277 will queue such an event and block on it. If so, we cannot 00278 queue&block (we'd deadlock), so we do the query manually. 00279 VetoType - If this function returns false, this parameter will describe 00280 who failed the query profile change. The below optional 00281 parameter will contain the name of said vetoer. 00282 VetoName - This optional parameter will get the name of the vetoer (ie 00283 devinst, service name, application name, etc). If VetoName 00284 is supplied, the caller must free the buffer returned. 00285 00286 Return Value: 00287 00288 NTSTATUS. 00289 00290 --*/ 00291 { 00292 PROFILE_WORK_ITEM profileWorkItem; 00293 NTSTATUS status; 00294 BOOLEAN arrivingDockFound; 00295 PLIST_ENTRY listEntry ; 00296 PDEVICE_NODE devNode ; 00297 00298 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00299 00300 // 00301 // Acquire the lock on the list of dock devices and determine whether any 00302 // dock devnodes are arriving. 00303 // 00304 ExAcquireFastMutex(&IopDockDeviceListLock); 00305 00306 ASSERT(IopDocksInTransition) ; 00307 00308 arrivingDockFound = FALSE ; 00309 for (listEntry = IopDockDeviceListHead.Flink; 00310 listEntry != &(IopDockDeviceListHead); 00311 listEntry = listEntry->Flink ) { 00312 00313 devNode = CONTAINING_RECORD(listEntry, 00314 DEVICE_NODE, 00315 DockInfo.ListEntry); 00316 00317 ASSERT((devNode->DockInfo.DockStatus != DOCK_NOTDOCKDEVICE)&& 00318 (devNode->DockInfo.DockStatus != DOCK_EJECTIRP_COMPLETED)) ; 00319 00320 if (devNode->DockInfo.DockStatus == DOCK_ARRIVING) { 00321 00322 arrivingDockFound = TRUE ; 00323 } 00324 } 00325 00326 // 00327 // Release the lock on the list of dock devices 00328 // 00329 ExReleaseFastMutex(&IopDockDeviceListLock); 00330 00331 if (SubsumingExistingDeparture) { 00332 00333 ASSERT(IopProfileChangeCancelRequired) ; 00334 // 00335 // We're nesting. Work off the last query, and don't requery. 00336 // 00337 return STATUS_SUCCESS ; 00338 } 00339 00340 if (arrivingDockFound) { 00341 00342 // 00343 // We currently don't actually query for hardware profile change on a 00344 // dock event as the user may have the lid closed. If we ever find a 00345 // piece of hardware that needs to be updated *prior* to actually 00346 // switching over, we will have to remove this bit of code. 00347 // 00348 IopProfileChangeCancelRequired = FALSE ; 00349 return STATUS_SUCCESS ; 00350 } 00351 00352 PIDBGMSG(PIDBG_HWPROFILE, ("NTOSKRNL: Sending HW profile change [query]\n")) ; 00353 00354 status = IopRequestHwProfileChangeNotification( 00355 (LPGUID) &GUID_HWPROFILE_QUERY_CHANGE, 00356 InPnpEvent, 00357 VetoType, 00358 VetoName 00359 ); 00360 00361 if (NT_SUCCESS(status)) { 00362 IopProfileChangeCancelRequired = TRUE ; 00363 } else { 00364 IopProfileChangeCancelRequired = FALSE ; 00365 } 00366 return status ; 00367 }

VOID IopHardwareProfileSendCancel VOID   ) 
 

Definition at line 827 of file dockhwp.c.

References ASSERT_SEMA_NOT_SIGNALLED, IopProfileChangeSemaphore, IopRequestHwProfileChangeNotification(), NTSTATUS(), NULL, and PROFILE_PERHAPS_IN_PNPEVENT.

Referenced by IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), and IopHardwareProfileCommitStartedDock().

00832 : 00833 00834 This routine (internal to dockhwp.c) simply sends the cancel. 00835 00836 Arguments: 00837 00838 None. 00839 00840 Return Value: 00841 00842 Nodda. 00843 00844 --*/ 00845 { 00846 PROFILE_WORK_ITEM profileWorkItem; 00847 PNP_VETO_TYPE vetoType; 00848 NTSTATUS status; 00849 00850 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00851 PIDBGMSG(PIDBG_HWPROFILE, ("NTOSKRNL: Sending HW profile change [cancel]\n")) ; 00852 00853 IopRequestHwProfileChangeNotification( 00854 (LPGUID) &GUID_HWPROFILE_CHANGE_CANCELLED, 00855 PROFILE_PERHAPS_IN_PNPEVENT, 00856 NULL, 00857 NULL 00858 ) ; 00859 }

VOID IopHardwareProfileSendCommit VOID   ) 
 

Definition at line 795 of file dockhwp.c.

References ASSERT_SEMA_NOT_SIGNALLED, IopProfileChangeSemaphore, IopRequestHwProfileChangeNotification(), NULL, and PROFILE_PERHAPS_IN_PNPEVENT.

Referenced by IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCommitRemovedDock(), and IopHardwareProfileCommitStartedDock().

00800 : 00801 00802 This routine (internal to dockhwp.c) simply sends the change complete message. 00803 We do not wait for this, as it is asynchronous... 00804 00805 Arguments: 00806 00807 None. 00808 00809 Return Value: 00810 00811 Nodda. 00812 00813 --*/ 00814 { 00815 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00816 PIDBGMSG(PIDBG_HWPROFILE, ("NTOSKRNL: Sending HW profile change [commit]\n")) ; 00817 00818 IopRequestHwProfileChangeNotification( 00819 (LPGUID) &GUID_HWPROFILE_CHANGE_COMPLETE, 00820 PROFILE_PERHAPS_IN_PNPEVENT, 00821 NULL, 00822 NULL 00823 ); 00824 }

VOID IopHardwareProfileSetMarkedDocksEjected VOID   ) 
 

Definition at line 739 of file dockhwp.c.

References ASSERT, ASSERT_SEMA_NOT_SIGNALLED, DOCK_DEPARTING, DOCK_EJECTIRP_COMPLETED, DOCK_QUIESCENT, _DEVICE_NODE::DockInfo, IopDockDeviceListHead, IopDockDeviceListLock, and IopProfileChangeSemaphore.

Referenced by IopProcessCompletedEject().

00744 : 00745 00746 This routine moves any departing devnodes to the ejected state. If any 00747 subsequent enumeration lists the device as present, we know the eject 00748 failed and we appropriately cancel that piece of the profile change. 00749 IopHardwareProfileCancelRemovedDock can only be called after this function 00750 is called. 00751 00752 Arguments: 00753 00754 None. 00755 00756 Return Value: 00757 00758 Nodda. 00759 00760 --*/ 00761 { 00762 PLIST_ENTRY listEntry; 00763 PDEVICE_NODE devNode; 00764 00765 ASSERT_SEMA_NOT_SIGNALLED(&IopProfileChangeSemaphore) ; 00766 00767 // 00768 // Acquire the lock on the list of dock devices 00769 // 00770 ExAcquireFastMutex(&IopDockDeviceListLock); 00771 00772 for (listEntry = IopDockDeviceListHead.Flink; 00773 listEntry != &(IopDockDeviceListHead); 00774 listEntry = listEntry->Flink ) { 00775 00776 devNode = CONTAINING_RECORD(listEntry, 00777 DEVICE_NODE, 00778 DockInfo.ListEntry); 00779 00780 ASSERT((devNode->DockInfo.DockStatus == DOCK_QUIESCENT)|| 00781 (devNode->DockInfo.DockStatus == DOCK_DEPARTING)) ; 00782 if (devNode->DockInfo.DockStatus != DOCK_QUIESCENT) { 00783 00784 devNode->DockInfo.DockStatus = DOCK_EJECTIRP_COMPLETED ; 00785 } 00786 } 00787 00788 // 00789 // Release the lock on the list of dock devices 00790 // 00791 ExReleaseFastMutex(&IopDockDeviceListLock); 00792 }

NTSTATUS IopUpdateHardwareProfile OUT PBOOLEAN  ProfileChanged  ) 
 

Definition at line 862 of file dockhwp.c.

References ASSERT, CM_HARDWARE_PROFILE_STR_CURRENT_DOCK_INFO, CM_HARDWARE_PROFILE_STR_DATABASE, DOCK_NOTDOCKDEVICE, _DEVICE_NODE::DockInfo, ExAllocatePool, ExFreePool(), FALSE, HardwareProfileBusTypeACPI, IopDockDeviceCount, IopDockDeviceListHead, IopDockDeviceListLock, IopExecuteHardwareProfileChange(), IopOpenRegistryKey(), NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, and RtlInitUnicodeString().

Referenced by IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCommitRemovedDock(), and IopHardwareProfileCommitStartedDock().

00866 : 00867 00868 This routine scans the list of current dock devices, builds a list of serial 00869 numbers from those devices, and calls for the Hardware Profile to be 00870 changed, based on that list. 00871 00872 Arguments: 00873 00874 ProfileChanged - Supplies a variable to receive TRUE if the current hardware 00875 profile changes as a result of calling this routine. 00876 00877 Return Value: 00878 00879 NTSTATUS code. 00880 00881 --*/ 00882 { 00883 NTSTATUS status = STATUS_SUCCESS; 00884 PLIST_ENTRY listEntry; 00885 PDEVICE_NODE devNode; 00886 PWCHAR *profileSerialNumbers, *p; 00887 HANDLE hProfileKey=NULL; 00888 ULONG len, numProfiles; 00889 HANDLE hCurrent, hIDConfigDB; 00890 UNICODE_STRING unicodeName; 00891 00892 // 00893 // Acquire the lock on the list of dock devices 00894 // 00895 ExAcquireFastMutex(&IopDockDeviceListLock); 00896 00897 // 00898 // Update the flag for Ejectable Docks 00899 // 00900 RtlInitUnicodeString(&unicodeName, CM_HARDWARE_PROFILE_STR_DATABASE); 00901 if(NT_SUCCESS(IopOpenRegistryKey(&hIDConfigDB, 00902 NULL, 00903 &unicodeName, 00904 KEY_READ, 00905 FALSE) )) { 00906 00907 RtlInitUnicodeString(&unicodeName, CM_HARDWARE_PROFILE_STR_CURRENT_DOCK_INFO); 00908 if(NT_SUCCESS(IopOpenRegistryKey(&hCurrent, 00909 hIDConfigDB, 00910 &unicodeName, 00911 KEY_READ | KEY_WRITE, 00912 FALSE) )) { 00913 00914 RtlInitUnicodeString(&unicodeName, REGSTR_VAL_EJECTABLE_DOCKS); 00915 ZwSetValueKey(hCurrent, 00916 &unicodeName, 00917 0, 00918 REG_DWORD, 00919 &IopDockDeviceCount, 00920 sizeof(IopDockDeviceCount)); 00921 ZwClose(hCurrent); 00922 } 00923 ZwClose(hIDConfigDB); 00924 } 00925 00926 if (IopDockDeviceCount == 0) { 00927 // 00928 // if there are no dock devices, the list should 00929 // contain a single null entry, in addition to the null 00930 // termination. 00931 // 00932 numProfiles = 1; 00933 ASSERT(IsListEmpty(&IopDockDeviceListHead)); 00934 } else { 00935 numProfiles = IopDockDeviceCount; 00936 ASSERT(!IsListEmpty(&IopDockDeviceListHead)); 00937 } 00938 00939 // 00940 // Allocate space for a null-terminated list of SerialNumber lists. 00941 // 00942 len = (numProfiles+1)*sizeof(PWCHAR); 00943 profileSerialNumbers = ExAllocatePool(NonPagedPool, len); 00944 00945 if (profileSerialNumbers) { 00946 00947 p = profileSerialNumbers; 00948 00949 // 00950 // Create the list of Serial Numbers 00951 // 00952 for (listEntry = IopDockDeviceListHead.Flink; 00953 listEntry != &(IopDockDeviceListHead); 00954 listEntry = listEntry->Flink ) { 00955 00956 devNode = CONTAINING_RECORD(listEntry, 00957 DEVICE_NODE, 00958 DockInfo.ListEntry); 00959 00960 // 00961 // ADRIAO BUGBUG 11/11/98 - 00962 // Is everything in the quiescent state here? 00963 // 00964 ASSERT(devNode->DockInfo.DockStatus != DOCK_NOTDOCKDEVICE) ; 00965 if (devNode->DockInfo.SerialNumber) { 00966 *p = devNode->DockInfo.SerialNumber; 00967 p++; 00968 } 00969 } 00970 00971 ExReleaseFastMutex(&IopDockDeviceListLock); 00972 00973 if (p == profileSerialNumbers) { 00974 // 00975 // Set a single list entry to NULL if we look to be in an "undocked" 00976 // profile 00977 // 00978 *p = NULL; 00979 p++; 00980 } 00981 00982 // 00983 // Null-terminate the list 00984 // 00985 *p = NULL; 00986 00987 numProfiles = (ULONG)(p - profileSerialNumbers); 00988 00989 // 00990 // Change the current Hardware Profile based on the new Dock State 00991 // and perform notification that the Hardware Profile has changed 00992 // 00993 status = IopExecuteHardwareProfileChange(HardwareProfileBusTypeACPI, 00994 profileSerialNumbers, 00995 numProfiles, 00996 &hProfileKey, 00997 ProfileChanged); 00998 if (hProfileKey) { 00999 ZwClose(hProfileKey); 01000 } 01001 ExFreePool (profileSerialNumbers); 01002 01003 } else { 01004 01005 ExReleaseFastMutex(&IopDockDeviceListLock); 01006 01007 status = STATUS_INSUFFICIENT_RESOURCES; 01008 } 01009 01010 return status; 01011 }


Variable Documentation

ULONG IopDockDeviceCount
 

Definition at line 72 of file dockhwp.c.

Referenced by IopHardwareProfileCommitRemovedDock(), IopHardwareProfileMarkDock(), IopInitializePlugPlayServices(), and IopUpdateHardwareProfile().

LIST_ENTRY IopDockDeviceListHead
 

Definition at line 71 of file dockhwp.c.

Referenced by IopHardwareProfileCancelTransition(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopHardwareProfileSetMarkedDocksEjected(), IopInitializePlugPlayServices(), and IopUpdateHardwareProfile().

FAST_MUTEX IopDockDeviceListLock
 

Definition at line 73 of file dockhwp.c.

Referenced by IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopHardwareProfileSetMarkedDocksEjected(), IopInitializePlugPlayServices(), and IopUpdateHardwareProfile().

LONG IopDocksInTransition
 

Definition at line 76 of file dockhwp.c.

Referenced by IopHardwareProfileBeginTransition(), IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileCommitStartedDock(), IopHardwareProfileMarkDock(), and IopHardwareProfileQueryChange().

BOOLEAN IopProfileChangeCancelRequired
 

Definition at line 75 of file dockhwp.c.

Referenced by IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileCommitStartedDock(), and IopHardwareProfileQueryChange().

KSEMAPHORE IopProfileChangeSemaphore
 

Definition at line 74 of file dockhwp.c.

Referenced by IoInitSystem(), IopHardwareProfileBeginTransition(), IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCancelTransition(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileCommitStartedDock(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopHardwareProfileSendCancel(), IopHardwareProfileSendCommit(), and IopHardwareProfileSetMarkedDocksEjected().


Generated on Sat May 15 19:43:28 2004 for test by doxygen 1.3.7