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<SpoolerServiceTimeout) &&
(serviceStatus.dwCurrentState != SERVICE_RUNNING); i++) {
//
// Sleep for a sec.
//
Sleep(1000);
TRACE((DEBUG_TSHRSRV_DEBUG,"RDPPNUTL: Spooler is still initializing.\n"));
//
// Try again.
//
if (!QueryServiceStatus(hService, &serviceStatus)) {
result = GetLastError();
TRACE((DEBUG_TSHRSRV_ERROR,
"RDPPNUTL: QueryServiceStatus on spooler failed with %08X.\n",
result));
goto CleanUpAndExit;
}
}
//
// Sucess if the spooler is now running.
//
if (serviceStatus.dwCurrentState == SERVICE_RUNNING) {
result = ERROR_SUCCESS;
}
else {
TRACE((DEBUG_TSHRSRV_WARN,
"RDPPNUTL: Spooler is not running after a timeout or error.\n")
);
result = E_FAIL;
}
CleanUpAndExit:
if (pServiceConfig != NULL) {
TSHeapFree(pServiceConfig);
}
if (scManager != NULL) {
CloseServiceHandle(scManager);
}
if (hService != NULL) {
CloseServiceHandle(hService);
}
TRACE((DEBUG_TSHRSRV_DEBUG,"RDPPNUTL: Exit WaitForSpoolerToStart.\n"));
return result;
}
解析:45秒
0: kd> 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<SpoolerServiceTimeout) &&
(serviceStatus.dwCurrentState != SERVICE_RUNNING); i++) {
//
// Sleep for a sec.
//
Sleep(1000);
TRACE((DEBUG_TSHRSRV_DEBUG,"RDPPNUTL: Spooler is still initializing.\n"));
TRACE((DEBUG_TSHRSRV_DEBUG,"RDPPNUTL: Exit WaitForSpoolerToStart.\n"));
return result;
}
04:47:42.390 898061FC.E1757188 RDPPNUTL: Spooler is still initializing.
04:47:42.390 898061FC.E1757188 RDPPNUTL: Exit WaitForSpoolerToStart.
注:可以打开调试看看PRINTSPOOLER服务什么时候启动成功
0: kd> 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<count; i++) {
if (pPrinterInfoi.pPrinterName) {
DBGMSG(DBG_TRACE, ("RDPPNUTL: Checking %ws for TS printer status.\n",
pPrinterInfoi.pPrinterName));
//
// Is this a TS printer?
//
if (pPrinterInfoi.pPortName &&
(pPrinterInfoi.pPortName0 == 'T') &&
(pPrinterInfoi.pPortName1 == 'S') &&
ISNUM(pPrinterInfoi.pPortName2)) {
DBGMSG(DBG_ERROR, ("RDPPNUTL: %ws is a TS printer.\n",
pPrinterInfoi.pPrinterName));
}
else {
continue;
}
//
// Purge and delete the printer.
//
if (OpenPrinter(pPrinterInfoi.pPrinterName, &hPrinter, &defaults)) {
if (!SetPrinter(hPrinter, 0, NULL, PRINTER_CONTROL_PURGE) ||
!DeletePrinter(hPrinter)) {
DBGMSG(DBG_ERROR, ("RDPPNUTL: Error deleting printer %ws.\n",
pPrinterInfoi.pPrinterName));
}
else {
DBGMSG(DBG_ERROR, ("RDPPNUTL: Successfully deleted %ws.\n",
pPrinterInfoi.pPrinterName));
}
ClosePrinter(hPrinter);
}
else {
DBGMSG(DBG_ERROR,
("RDPPNUTL: OpenPrinter failed for %ws. Error: %08X.\n",
pPrinterInfoi.pPrinterName,
GetLastError())
);
}
}
else {
DBGMSG(DBG_ERROR, ("RDPPNUTL: Printer %ld is NULL\n", i));
}
}
DBGMSG(DBG_TRACE, ("RDPPNUTL: DeleteTSPrinters exit\n"));
}