rdpwsx!RDPPNUTL_RemoveAllTSPrinters函数分析

0: kd> p

04:47:22.343 898061FC.E1757188 TShrSRV: ICASRV callback table saved

rdpwsx!WsxInitialize+0x65:

001b:70fbe182 e86c1a0000 call rdpwsx!RDPPNUTL_RemoveAllTSPrinters (70fbfbf3)

0: kd> p

04:47:22.359 898061FC.E1757188 RDPPNUTL: RDPPNUTL_RemoveAllTSPrinters entry

04:47:22.359 898061FC.E1757188 RDPPNUTL: Loading registry settings.

04:47:22.359 898061FC.E1757188 RDPPNUTL: Failed to read spooler timeout value.: 00000002.

04:47:22.359 898061FC.E1757188 RDPPNUTL: Enter WaitForSpoolerToStart.

04:47:23.359 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

AudioSrv: pid=972

WIARPC:Exception 0x6ba calling WIA RPC server

04:47:25.359 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:26.359 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:27.359 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:28.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:29.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:30.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:30.937 896CEADC.E174F1E8 TERMSRV: -|--------------------------------------------|-

04:47:30.953 896CEADC.E174F1E8 TERMSRV: Client SPN: NT AUTHORITY\SYSTEM

04:47:30.968 896CEADC.E174F1E8 TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_PKT_PRIVACY

04:47:30.968 896CEADC.E174F1E8 TERMSRV: Authentication service: RPC_C_AUTHN_WINNT

04:47:30.968 896CEADC.E174F1E8 TERMSRV: -|--------------------------------------------|-

04:47:30.968 8976078C.E1738DE8 TERMSRV: -|--------------------------------------------|-

04:47:30.968 8976078C.E1738DE8 TERMSRV: Client SPN: NT AUTHORITY\SYSTEM

04:47:30.968 8976078C.E1738DE8 TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_PKT_PRIVACY

04:47:30.968 8976078C.E1738DE8 TERMSRV: Authentication service: RPC_C_AUTHN_WINNT

04:47:30.968 8976078C.E1738DE8 TERMSRV: -|--------------------------------------------|-

04:47:31.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

WARNING: This break is not a step/trace completion.

The last command has been cleared to prevent

accidental continuation of this unrelated event.

Check the event, location and thread before resuming.

Break instruction exception - code 80000003 (first chance)

*******************************************************************************

* *

* You are seeing this message because you pressed either *

* CTRL+C (if you run console kernel debugger) or, *

* CTRL+BREAK (if you run GUI kernel debugger), *

* on your debugger machine's keyboard. *

* *

* THIS IS NOT A BUG OR A SYSTEM CRASH *

* *

* If you did not intend to break into the debugger, press the "g" key, then *

* press the "Enter" key now. This message might immediately reappear. If it *

* does, press "g" and "Enter" again. *

* *

*******************************************************************************

nt!RtlpBreakWithStatusInstruction:

80ae0d1c cc int 3

0: kd> g

04:47:32.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:33.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:34.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:35.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:36.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

456.1144> AUTOENRL: RegisterAutoEnrollmentProcessing exiting with error: (0x80004004)

00000:Ageint(1):Couldn't turn CSC ON!!!!!!!!!

WINMM(p456:t460): ClientUpdatePnpInfo: warning: called in winlogon before logged on

WINMM(p456:t472): ClientUpdatePnpInfo: warning: called in winlogon before logged on

04:47:37.203 896CEADC.E174F1E8 TERMSRV: -|--------------------------------------------|-

04:47:37.218 896CEADC.E174F1E8 TERMSRV: Client SPN: NT AUTHORITY\SYSTEM

04:47:37.218 896CEADC.E174F1E8 TERMSRV: Authentication level: RPC_C_AUTHN_LEVEL_PKT_PRIVACY

04:47:37.218 896CEADC.E174F1E8 TERMSRV: Authentication service: RPC_C_AUTHN_WINNT

04:47:37.218 896CEADC.E174F1E8 TERMSRV: -|--------------------------------------------|-

04:47:37.218 896CEADC.E174F1E8 TERMSRV: WinStationQueryInformation LogonId=0, Class=6

04:47:37.218 896CEADC.E174F1E8 TERMSRV: RpcCheckClientAccess, AccessCheckAndAuditAlarm(0) returned no error

04:47:37.218 896CEADC.E174F1E8 TERMSRV: WinStationQueryInformation LogonId=0, Class=6, Status=0x0

WINMM(p456:t460): ClientUpdatePnpInfo: warning: called in winlogon before logged on

WINMM(p456:t472): ClientUpdatePnpInfo: warning: called in winlogon before logged on

WINMM(p456:t460): ClientUpdatePnpInfo: warning: called in winlogon before logged on

WINMM(p456:t472): ClientUpdatePnpInfo: warning: called in winlogon before logged on

WINMM(p456:t460): ClientUpdatePnpInfo: warning: called in winlogon before logged on

WINMM(p456:t472): ClientUpdatePnpInfo: warning: called in winlogon before logged on

04:47:37.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:38.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:39.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:40.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

04:47:41.375 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.

00000:Ageint(1):Couldn't turn CSC ON!!!!!!!!!

WINMM(p456:t460): ClientUpdatePnpInfo: warning: called in winlogon before logged on

WINMM(p456:t472): ClientUpdatePnpInfo: warning: called in winlogon before logged on

MSV1_0.dll\] \[CRITICAL\] SpAcceptCredentials: Collision from NlpFindActiveLogon for 0:0x3e4 WINMM(p456:t460): ClientUpdatePnpInfo: warning: called in winlogon before logged on WINMM(p456:t472): ClientUpdatePnpInfo: warning: called in winlogon before logged on 04:47:42.390 898061FC.E1757188 RDPPNUTL: Spooler is still initializing. 04:47:42.390 898061FC.E1757188 RDPPNUTL: Exit WaitForSpoolerToStart. WINMM(p456:t460): ClientUpdatePnpInfo: warning: called in winlogon before logged on WINMM(p456:t472): ClientUpdatePnpInfo: warning: called in winlogon before logged on \[SENS\] RegQueryValueEx(SENS_DEBUG_LEVEL) failed with 0x2 \[05B0

TftpdServiceMain: Parameters...

Debug flags : 0x000F000F

Hash table size : 256 buckets

Buffer low water-mark : 5 buffers

Buffer high water-mark : 256 buffers

Max retries : 10 attempts

Root directory : \tftpdroot\

Valid client mask : *.*.*.*

Valid read file mask : *

Valid master mask : *.*.*.*

Valid write file mask : *

SENS\] \[-3565781\] Started successfully. \[05B0\] TftpdIoInitializeSocketContext(socket = master): TID = \<0.0.0.0:69\>. \[0604\] TftpdIoReadNotification(socket = master). \[0604\] TftpdIoPostReceiveBuffer(buffer = 00000000, socket = master). \[0604\] TftpdIoAllocateBuffer(socket = master). \[0604\] TftpdIoPostReceiveBuffer(buffer = 004548A8). \[0604\] TftpdIoPostReceiveBuffer(buffer = 00000000, socket = master). \[0604\] TftpdIoAllocateBuffer(socket = master). \[0604\] TftpdIoPostReceiveBuffer(buffer = 00454B20). \[0604\] TftpdIoPostReceiveBuffer(buffer = 00000000, socket = master). \[0604\] TftpdIoAllocateBuffer(socket = master). \[0604\] TftpdIoPostReceiveBuffer(buffer = 00454D98). \[0604\] TftpdIoPostReceiveBuffer(buffer = 00000000, socket = master). \[0604\] TftpdIoAllocateBuffer(socket = master). \[0604\] TftpdIoPostReceiveBuffer(buffer = 00455010). \[0604\] TftpdIoPostReceiveBuffer(buffer = 00000000, socket = master). \[0604\] TftpdIoAllocateBuffer(socket = master). \[0604\] TftpdIoPostReceiveBuffer(buffer = 00455288). \[05B0\] TftpdServiceMain(): Service running. TftpdServiceMain(): Service running.Debug flags: 0x000F000F 04:47:42.687 898061FC.E1757188 RDPPNUTL: First EnumPrinters succeeded. 04:47:42.687 898061FC.E1757188 RDPPNUTL: DeleteTSPrinters entry 04:47:42.687 898061FC.E1757188 RDPPNUTL: DeleteTSPrinters exit 04:47:42.687 898061FC.E1757188 TShrSRV: RDPPNUTL_RemoveAllTSPrinters exit 04:47:42.687 898061FC.E1757188 TShrSRV: TSrvMainThread created D:\\srv03rtm\\termsrv\>grep "RDPPNUTL_RemoveAllTSPrinters entry" -nr D:\\srv03rtm\\termsrv D:\\srv03rtm\\termsrv/rdpwsx/rdpex/rdppnutl.c:113: TRACE((DEBUG_TSHRSRV_DEBUG,"RDPPNUTL: RDPPNUTL_RemoveAllTSPrinters entry\\n")); 04:47:22.359 898061FC.E1757188 RDPPNUTL: Loading registry settings. void LoadRDPPNUTLRegistrySettings() { HKEY regKey; DWORD dwResult; DWORD type; DWORD sz; TRACE((DEBUG_TSHRSRV_DEBUG,"RDPPNUTL: Loading registry settings.\\n")); // // Open the registry key. // dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, DEVICERDR_REG_NAME, 0, KEY_READ, \®Key); if (dwResult == ERROR_SUCCESS) { #define DEVICERDR_REG_NAME REG_CONTROL_TSERVER L"\\\\AddIns\\\\Terminal Server Redirector" #define DEVICERDR_REG_NAME_A REG_CONTROL_TSERVER_A "\\\\AddIns\\\\Terminal Server Redirector" /\* \* Device Redirection Values \*/ #define DEVICERDR_SESSIONID L"TSSessionID" #define DEVICERDR_SESSIONID_A "TSSessionID" #define DEVICERDR_WAITFORSPOOLTIMEOUT L"WaitForSpoolerTimeOut" #define DEVICERDR_WAITFORSPOOLTIMEOUT_A "WaitForSpoolerTimeOut" if (dwResult == ERROR_SUCCESS) { // // Read the "wait for spooler" timeout value. // sz = sizeof(SpoolerServiceTimeout); dwResult = RegQueryValueEx( regKey, DEVICERDR_WAITFORSPOOLTIMEOUT, NULL, \&type, (PBYTE)\&SpoolerServiceTimeout, \&sz ); if (dwResult != ERROR_SUCCESS){ TRACE((DEBUG_TSHRSRV_WARN, "RDPPNUTL: Failed to read spooler timeout value.: %08X.\\n", dwResult)); } else { TRACE((DEBUG_TSHRSRV_WARN, "RDPPNUTL: Spooler timeout value is %ld.\\n", SpoolerServiceTimeout)); } 04:47:22.359 898061FC.E1757188 RDPPNUTL: Failed to read spooler timeout value.: 00000002. DWORD RDPPNUTL_RemoveAllTSPrinters() { // // Load registry settings for this module. // LoadRDPPNUTLRegistrySettings(); // // Wait until the spooler has finished initializing. // status = WaitForSpoolerToStart(); if (status != ERROR_SUCCESS) { TRACE(( DEBUG_TSHRSRV_DEBUG, "RDPPNUTL: RDPPNUTL_RemoveAllTSPrinters exiting because spooler failed to start.\\n" )); return status; } WaitForSpoolerToStart rdppnutl.c (termsrv\\rdpwsx\\rdpex) 133 DWORD WaitForSpoolerToStart() /\*++ Routine Description: Waits until the spooler finishes initializing or until a timeout period elapses. Arguments: Return Value: Returns ERROR_SUCCESS if the spooler successfully initialized. Otherwise, an error code is returned. --\*/ { SC_HANDLE scManager = NULL; SC_HANDLE hService = NULL; DWORD result = ERROR_SUCCESS; SERVICE_STATUS serviceStatus; DWORD i; QUERY_SERVICE_CONFIG \*pServiceConfig = NULL; DWORD bufSize; TRACE((DEBUG_TSHRSRV_DEBUG,"RDPPNUTL: Enter WaitForSpoolerToStart.\\n")); // // Open the service control manager. // scManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS); if (scManager == NULL) { result = GetLastError(); TRACE((DEBUG_TSHRSRV_ERROR,"RDPPNUTL: OpenSCManager failed with %08X.\\n", result)); goto CleanUpAndExit; } // // Open the spooler service. // hService = OpenService(scManager, SPOOLER, SERVICE_ALL_ACCESS); if (hService == NULL) { result = GetLastError(); TRACE((DEBUG_TSHRSRV_ERROR, "RDPPNUTL: OpenService on spooler failed with %08X.\\n", result)); goto CleanUpAndExit; } // // If the spooler is currently running, that is all we need to know. // if (!QueryServiceStatus(hService, \&serviceStatus)) { result = GetLastError(); TRACE((DEBUG_TSHRSRV_ERROR, "RDPPNUTL: QueryServiceStatus on spooler failed with %08X.\\n", result)); goto CleanUpAndExit; } else if (serviceStatus.dwCurrentState == SERVICE_RUNNING) { TRACE((DEBUG_TSHRSRV_DEBUG,"RDPPNUTL: Spooler is running.\\n")); result = ERROR_SUCCESS; goto CleanUpAndExit; } // // Size the spooler service query configuration buffer. This API should // fail with ERROR_INSUFFICIENT_BUFFER, so we can get the size of the // buffer before we call the function with real parameters. // if (!QueryServiceConfig(hService, NULL, 0, \&bufSize) \&\& (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { pServiceConfig = (QUERY_SERVICE_CONFIG \*)TSHeapAlloc( HEAP_ZERO_MEMORY, bufSize, TS_HTAG_TSS_SPOOLERINFO ); if (pServiceConfig == NULL) { TRACE((DEBUG_TSHRSRV_ERROR,"RDPPNUTL: ALLOCMEM failed. Error: %08X.\\n", GetLastError())); result = ERROR_OUTOFMEMORY; goto CleanUpAndExit; } } else { TRACE((DEBUG_TSHRSRV_ERROR,"RDPPNUTL: QueryServiceConfig unexpected return.\\n")); result = E_UNEXPECTED; goto CleanUpAndExit; } // // Get the spooler's configuration information. // if (!QueryServiceConfig(hService, pServiceConfig, bufSize, \&bufSize)) { TRACE((DEBUG_TSHRSRV_ERROR,"RDPPNUTL: QueryServiceConfig failed: %08X.\\n", GetLastError())); result = GetLastError(); goto CleanUpAndExit; } // // If the spooler is not automatically configured to start on demand or // automatically on system start then that is all we need to know. // if (pServiceConfig-\>dwStartType != SERVICE_AUTO_START) { TRACE((DEBUG_TSHRSRV_WARN,"RDPPNUTL: Spooler not configured to start.\\n")); result = E_FAIL; goto CleanUpAndExit; } // // Poll the service status until we timeout or until the spooler // starts. // for (i=0; (i\ x rdpwsx!SpoolerServiceTimeout 70fcf5c0 rdpwsx!SpoolerServiceTimeout = 0x2d ////////////////////////////////////////////////////////////// // // Globals to this Module // // Number of seconds to wait for the spooler to finish initializing. DWORD SpoolerServiceTimeout = 45; // // Poll the service status until we timeout or until the spooler // starts. // for (i=0; (i\ x nt!kd_\*Spooler\* 80b18a64 nt!Kd_PRINTSPOOLER_Mask = 0 注: else { TRACE((DEBUG_TSHRSRV_DEBUG,"RDPPNUTL: First EnumPrinters succeeded.\\n")); status = ERROR_SUCCESS; pPrinterInfo = (PRINTER_INFO_5 \*)stackBuf; } // // Delete all the TS printers. We allow ERROR_INSUFFICIENT_BUFFER here because // a second invokation of EnumPrinters may have missed a few last-minute // printer additions. // if ((status == ERROR_SUCCESS) \|\| (status == ERROR_INSUFFICIENT_BUFFER)) { DeleteTSPrinters(pPrinterInfo, cReturnedStructs); status = ERROR_SUCCESS; } // // Release the printer info buffer. // if (buf != NULL) { TSHeapFree(buf); } TRACE((DEBUG_TSHRSRV_DEBUG,"TShrSRV: RDPPNUTL_RemoveAllTSPrinters exit\\n")); return status; } 04:47:42.687 898061FC.E1757188 RDPPNUTL: First EnumPrinters succeeded. 04:47:42.687 898061FC.E1757188 RDPPNUTL: DeleteTSPrinters entry 04:47:42.687 898061FC.E1757188 RDPPNUTL: DeleteTSPrinters exit 04:47:42.687 898061FC.E1757188 TShrSRV: RDPPNUTL_RemoveAllTSPrinters exit void DeleteTSPrinters( IN PRINTER_INFO_5 \*pPrinterInfo, IN DWORD count ) /\*++ Routine Description: Actually performs the printer deletion. Arguments: pPrinterInfo - All printer queues on the system. count - Number of printers in pPrinterInfo Return Value: NA --\*/ { DWORD i; DWORD regValueDataType; DWORD sessionID; HANDLE hPrinter = NULL; DWORD bufSize; PRINTER_DEFAULTS defaults = {NULL, NULL, PRINTER_ALL_ACCESS}; DBGMSG(DBG_TRACE, ("RDPPNUTL: DeleteTSPrinters entry\\n")); for (i=0; i\