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

ioerr.c File Reference

#include "pch.h"

Go to the source code of this file.

Functions

HANDLE IoepInitErrLog (IN ULONG KeyType, IN PVOID Key, IN ULONG ulFlags)
PERRTHREAD IoepFindErrThread (IN ULONG KeyType, IN PVOID Key)
PERRTHREAD IoepNewErrThread (IN ULONG KeyType, IN PVOID Key)
VOID IoepLogErr (IN ULONG KeyType, IN PVOID Key, IN CONST GUID *ComponentGuid, IN ULONG ErrCode, IN PWSTR TextData OPTIONAL, IN ULONG DataBlkType, IN ULONG DataBlkLen OPTIONAL, IN PVOID DataBlock OPTIONAL, IN CONST GUID *MofGuid OPTIONAL)
VOID IoepFreeErrStack (IN PERRENTRY ErrStack)
PERRMODULE IoepFindErrModule (IN CONST GUID *ComponentGuid)
NTSTATUS IoepExtractErrData (IN PERRENTRY ErrStack, OUT PVOID Buffer, IN ULONG BuffSize, OUT PULONG DataSize OPTIONAL)
NTSTATUS IoepFireWMIEvent (IN PERRINFO ErrInfo, IN PWSTR InstanceName)
NTSTATUS IoepHandleErrCase (IN PERRINFO ErrInfo, IN PERRCASE ErrCase, IN ULONG Method, OUT PUNICODE_STRING unicodeMsg OPTIONAL)
PERRHANDLER IoepFindErrHandler (IN CONST GUID *ComponentGuid, IN ULONG HandlerIndex)
BOOLEAN IoepMatchErrIDPath (IN PERRINFO ErrInfo, IN PERRID ErrIDPath, IN ULONG NumErrIDs)
NTSTATUS IoepGetErrMessage (IN PMSGDATA MsgData, IN PERRINFO ErrInfo, OUT PUNICODE_STRING unicodeMsg)
NTSTATUS IoepCatMsgArg (IN OUT PUNICODE_STRING unicodeMsg, IN PMSGARG MsgArg, IN PERRINFO ErrInfo)
NTSTATUS IoepUnicodeStringCatN (IN OUT PUNICODE_STRING unicodeStr, IN PWSTR pwstr, IN ULONG len)
PERRCASEDB IoepGetErrCaseDB (VOID)


Function Documentation

NTSTATUS IoepCatMsgArg IN OUT PUNICODE_STRING  unicodeMsg,
IN PMSGARG  MsgArg,
IN PERRINFO  ErrInfo
 

Definition at line 1052 of file ioerr.c.

References _handlerdata::ComponentGuid, _errcasedb::DataBlkOffset, _errdata::DataBlkOffset, DBGPRINT, ENTER, EXIT, _handlerdata::HandlerIndex, IOEDATA_PRIVATE, IOEDATA_TEXT, IOEDATA_WSTRING, IoepFindErrHandler(), IoepGetErrCaseDB(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _handlerdata::Param, PERRHANDLER, PROCNAME, RtlAppendUnicodeToString(), STATUS_IOE_DATABASE_NOT_READY, and _errdata::TextDataOffset.

Referenced by IoepGetErrMessage().

01059 : 01060 This routine appends the substituted message argument to the unicode 01061 string if there is enough space. Otherwise, STATUS_BUFFER_TOO_SMALL is 01062 returned. 01063 01064 Arguments: 01065 unicodeMsg - points to the target unicode message 01066 MsgArg - points to the message argument structure 01067 ErrInfo - points to the error info. 01068 01069 Return Value: 01070 Success - returns STATUS_SUCCESS 01071 Failure - returns NT status code 01072 01073 --*/ 01074 { 01075 PROCNAME("IoepCatMsgArg"); 01076 NTSTATUS status = STATUS_SUCCESS; 01077 PERRCASEDB ErrCaseDB; 01078 01079 PAGED_CODE(); 01080 ENTER(2, ("(Msg=%S,pMsgArg=%p,ErrInfo=%p)\n", 01081 unicodeMsg->Buffer, MsgArg, ErrInfo)); 01082 01083 ErrCaseDB = IoepGetErrCaseDB(); 01084 if (ErrCaseDB != NULL) 01085 { 01086 if (MsgArg->ErrIDIndex < ErrInfo->NumErrEntries) 01087 { 01088 PERRDATA ErrData; 01089 ANSI_STRING ansiStr; 01090 UNICODE_STRING unicodeStr; 01091 PHANDLERDATA HandlerData; 01092 PERRHANDLER ErrHandler; 01093 01094 ErrData = &ErrInfo->ErrEntries[MsgArg->ErrIDIndex]; 01095 switch (MsgArg->ArgType) 01096 { 01097 case IOEDATA_TEXT: 01098 status = RtlAppendUnicodeToString( 01099 unicodeMsg, 01100 (PWSTR)((PUCHAR)ErrInfo + 01101 ErrData->TextDataOffset)); 01102 if (!NT_SUCCESS(status)) 01103 { 01104 DBGPRINT(("failed to append unicode string (rc=%x)\n", 01105 status)); 01106 } 01107 break; 01108 01109 case IOEDATA_WSTRING: 01110 status = RtlAppendUnicodeToString( 01111 unicodeMsg, 01112 (PWSTR)((PUCHAR)ErrInfo + 01113 ErrData->DataBlkOffset)); 01114 if (!NT_SUCCESS(status)) 01115 { 01116 DBGPRINT(("failed to append unicode string argument (rc=%x)\n", 01117 status)); 01118 } 01119 break; 01120 01121 case IOEDATA_PRIVATE: 01122 HandlerData = (PHANDLERDATA)((ULONG_PTR)ErrCaseDB + 01123 ErrCaseDB->DataBlkOffset + 01124 MsgArg->ArgDataOffset); 01125 ErrHandler = IoepFindErrHandler(&HandlerData->ComponentGuid, 01126 HandlerData->HandlerIndex); 01127 if (ErrHandler != NULL) 01128 { 01129 status = ErrHandler(ErrData, HandlerData->Param); 01130 } 01131 break; 01132 01133 default: 01134 DBGPRINT(("invalid message argument type %d\n", 01135 MsgArg->ArgType)); 01136 } 01137 } 01138 else 01139 { 01140 status = STATUS_UNSUCCESSFUL; 01141 DBGPRINT(("failed to find error entry\n")); 01142 } 01143 } 01144 else 01145 { 01146 status = STATUS_IOE_DATABASE_NOT_READY; 01147 DBGPRINT(("error case database not ready\n")); 01148 } 01149 01150 EXIT(2, ("=%x(Msg=%S)\n", status, unicodeMsg->Buffer)); 01151 return status; 01152 } //IoepCatMsgArg

NTSTATUS IoepExtractErrData IN PERRENTRY  ErrStack,
OUT PVOID  Buffer,
IN ULONG  BuffSize,
OUT PULONG DataSize  OPTIONAL
 

Definition at line 501 of file ioerr.c.

References ASSERT, Buffer, _errentry::DataBlk, _errdata::DataBlkLen, _errentry::DataBlkLen, _errdata::DataBlkOffset, _errentry::DataBlkType, _errdata::DataBlkType, _errinfo::DataTag, DBGPRINT, ENTER, _errinfo::ErrEntries, _errentry::ErrID, _errdata::ErrID, EXIT, IOE_ERRINFO_VERSION, IoepGetNextErrEntry, _errentry::MofGuid, _errdata::MofGuid, NTSTATUS(), NULL, _errinfo::NumErrEntries, PROCNAME, SIG_ERRINFO, _errinfo::Signature, _errinfo::Size, _errinfo::TagFlags, _errdata::TextDataOffset, _errentry::unicodeStr, and _errinfo::Version.

Referenced by IoErrGetErrData().

00509 : 00510 This routine stores the error stack data into a flat buffer. 00511 00512 Arguments: 00513 ErrStack - points to the error stack 00514 Buffer - points to the buffer for the data 00515 BuffSize - specifies the buffer size 00516 DataSize - points to the variable to receive the actual data size 00517 00518 Return Value: 00519 Success - returns STATUS_SUCCESS 00520 Failure - returns NT status code 00521 00522 --*/ 00523 { 00524 PROCNAME("IoepExtractErrData"); 00525 NTSTATUS status; 00526 PERRENTRY Err; 00527 ULONG len, i; 00528 00529 ASSERT(ErrStack != NULL); 00530 ASSERT((Buffer != NULL) && (BuffSize > 0) || (DataSize != NULL)); 00531 ENTER(2, ("(ErrStack=%p,Buff=%p,BuffSize=%d,pDataSize=%p)\n", 00532 ErrStack, Buffer, BuffSize, DataSize)); 00533 00534 for (Err = ErrStack, len = sizeof(ERRINFO) - sizeof(ERRDATA), i = 0; 00535 Err != NULL; 00536 Err = IoepGetNextErrEntry(Err), i++) 00537 { 00538 len += sizeof(ERRDATA) + 00539 Err->DataBlkLen + 00540 Err->unicodeStr.MaximumLength; 00541 } 00542 00543 if (len <= BuffSize) 00544 { 00545 if ((Buffer != NULL) && (len > 0)) 00546 { 00547 PERRINFO ErrInfo = (PERRINFO)Buffer; 00548 PUCHAR pBuff; 00549 00550 ErrInfo->Signature = SIG_ERRINFO; 00551 ErrInfo->Version = IOE_ERRINFO_VERSION; 00552 ErrInfo->Size = len; 00553 ErrInfo->DataTag = NULL; 00554 ErrInfo->TagFlags = 0; 00555 ErrInfo->NumErrEntries = i; 00556 pBuff = (PUCHAR)ErrInfo + sizeof(ERRINFO) + sizeof(ERRDATA)*(i - 1); 00557 for (Err = ErrStack, i = 0; 00558 Err != NULL; 00559 Err = IoepGetNextErrEntry(Err), i++) 00560 { 00561 ErrInfo->ErrEntries[i].ErrID = Err->ErrID; 00562 ErrInfo->ErrEntries[i].DataBlkType = Err->DataBlkType; 00563 ErrInfo->ErrEntries[i].DataBlkLen = Err->DataBlkLen; 00564 ErrInfo->ErrEntries[i].MofGuid = Err->MofGuid; 00565 00566 if (Err->unicodeStr.MaximumLength > 0) 00567 { 00568 ErrInfo->ErrEntries[i].TextDataOffset = pBuff - 00569 (PUCHAR)ErrInfo; 00570 RtlCopyMemory(pBuff, 00571 Err->unicodeStr.Buffer, 00572 Err->unicodeStr.MaximumLength); 00573 pBuff += Err->unicodeStr.MaximumLength; 00574 } 00575 else 00576 { 00577 ErrInfo->ErrEntries[i].TextDataOffset = 0; 00578 } 00579 00580 if (Err->DataBlk != NULL) 00581 { 00582 ErrInfo->ErrEntries[i].DataBlkOffset = pBuff - 00583 (PUCHAR)ErrInfo; 00584 RtlCopyMemory(pBuff, Err->DataBlk, Err->DataBlkLen); 00585 pBuff += Err->DataBlkLen; 00586 } 00587 else 00588 { 00589 ErrInfo->ErrEntries[i].DataBlkOffset = 0; 00590 } 00591 } 00592 } 00593 00594 status = STATUS_SUCCESS; 00595 } 00596 else 00597 { 00598 status = STATUS_BUFFER_TOO_SMALL; 00599 DBGPRINT(("buffer too small (size=%d,need=%d)\n", BuffSize, len)); 00600 } 00601 00602 if (DataSize != NULL) 00603 { 00604 *DataSize = len; 00605 } 00606 00607 EXIT(2, ("=%x(len=%d)\n", status, len)); 00608 return status; 00609 } //IoepExtractErrData

PERRHANDLER IoepFindErrHandler IN CONST GUID *  ComponentGuid,
IN ULONG  HandlerIndex
 

Definition at line 824 of file ioerr.c.

References ENTER, EXIT, _errmodule::HandlerTable, IoepFindErrModule(), NULL, _errmodule::NumErrHandlers, PERRHANDLER, and PROCNAME.

Referenced by IoepCatMsgArg(), and IoepHandleErrCase().

00830 : 00831 This routine find the error handler with the given module GUID and 00832 handler index. 00833 00834 Arguments: 00835 ComponentGuid - points to the GUID of the handler module 00836 HandlerIndex - index into handler table 00837 00838 Return Value: 00839 Success - returns pointer to error handler found 00840 Failure - returns NULL 00841 00842 --*/ 00843 { 00844 PROCNAME("IoepFindErrHandler"); 00845 PERRHANDLER ErrHandler = NULL; 00846 PERRMODULE ErrModule; 00847 00848 ENTER(2, ("(pGuid=%p,Index=%x)\n", ComponentGuid, HandlerIndex)); 00849 00850 ErrModule = IoepFindErrModule(ComponentGuid); 00851 00852 if ((ErrModule != NULL) && (HandlerIndex < ErrModule->NumErrHandlers)) 00853 { 00854 ErrHandler = ErrModule->HandlerTable[HandlerIndex]; 00855 } 00856 00857 EXIT(2, ("=%p\n", ErrHandler)); 00858 return ErrHandler; 00859 } //IoepFindErrHandler

PERRMODULE IoepFindErrModule IN CONST GUID *  ComponentGuid  ) 
 

Definition at line 456 of file ioerr.c.

References _errmodule::ComponentGuid, ENTER, EXIT, IoepErrListLock, IoepErrModuleListHead, NULL, and PROCNAME.

Referenced by IoepFindErrHandler(), and IoErrRegisterErrHandlers().

00461 : 00462 This routine finds a registered error module with a given module GUID. 00463 00464 Arguments: 00465 ComponentGuid - points to the GUID of the error module 00466 00467 Return Value: 00468 Success - returns pointer to error module found 00469 Failure - returns NULL 00470 00471 --*/ 00472 { 00473 PROCNAME("IoepFindErrModule"); 00474 PERRMODULE ErrModule = NULL; 00475 PLIST_ENTRY list; 00476 KIRQL Irql; 00477 00478 ENTER(2, ("(pGuid=%p)\n", ComponentGuid)); 00479 00480 ExAcquireSpinLock(&IoepErrListLock, &Irql); 00481 for (list = IoepErrModuleListHead.Flink; 00482 list != &IoepErrModuleListHead; 00483 list = list->Flink) 00484 { 00485 ErrModule = CONTAINING_RECORD(list, ERRMODULE, list); 00486 if (RtlEqualMemory(&ErrModule->ComponentGuid, 00487 ComponentGuid, 00488 sizeof(GUID))) 00489 { 00490 break; 00491 } 00492 ErrModule = NULL; 00493 } 00494 ExReleaseSpinLock(&IoepErrListLock, Irql); 00495 00496 EXIT(2, ("=%p\n", ErrModule)); 00497 return ErrModule; 00498 } //IoepFindErrModule

PERRTHREAD IoepFindErrThread IN ULONG  KeyType,
IN PVOID  Key
 

Definition at line 108 of file ioerr.c.

References _IO_STACK_LOCATION::DeviceObject, ENTER, EXIT, IoepErrListLock, IoepErrThreadListHead, IoGetCurrentIrpStackLocation, Key, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NULL, _IO_STACK_LOCATION::Parameters, PROCNAME, _errthread::ThreadKey, THREADKEY_IRP, THREADKEY_THREADID, and _errthread::ThreadKeyType.

Referenced by IoepInitErrLog(), and IoepLogErr().

00114 : 00115 This routine finds the error thread keyed by the given Key. 00116 00117 Arguments: 00118 KeyType - specifies the type of key. 00119 Key - points to the key that is used to locate the logging session. 00120 00121 Return Value: 00122 Success - returns the error thread handle found. 00123 Failure - returns NULL. 00124 00125 --*/ 00126 { 00127 PROCNAME("IoepFindErrThread"); 00128 PERRTHREAD ErrThread = NULL; 00129 PLIST_ENTRY list; 00130 KIRQL Irql; 00131 00132 ENTER(2, ("(KeyType=%x,Key=%p)\n", KeyType, Key)); 00133 00134 ExAcquireSpinLock(&IoepErrListLock, &Irql); 00135 for (list = IoepErrThreadListHead.Flink; 00136 list != &IoepErrThreadListHead; 00137 list = list->Flink) 00138 { 00139 ErrThread = CONTAINING_RECORD(list, ERRTHREAD, list); 00140 if (ErrThread->ThreadKeyType == KeyType) 00141 { 00142 switch (KeyType) 00143 { 00144 case THREADKEY_IRP: 00145 if ((PIRP)Key == ErrThread->ThreadKey.IrpKey.Irp) 00146 { 00147 break; 00148 } 00149 else 00150 { 00151 PIO_STACK_LOCATION IrpSp; 00152 00153 IrpSp = IoGetCurrentIrpStackLocation((PIRP)Key); 00154 if ((IrpSp->MajorFunction == 00155 ErrThread->ThreadKey.IrpKey.MajorFunction) && 00156 (IrpSp->MinorFunction == 00157 ErrThread->ThreadKey.IrpKey.MinorFunction) && 00158 RtlEqualMemory(&IrpSp->Parameters.Others, 00159 ErrThread->ThreadKey.IrpKey.Arguments, 00160 sizeof(PVOID)*4) && 00161 (IopDbgGetLowestDevice(IrpSp->DeviceObject) == 00162 ErrThread->ThreadKey.IrpKey.TargetDevice)) 00163 { 00164 break; 00165 } 00166 } 00167 break; 00168 00169 case THREADKEY_THREADID: 00170 if ((PKTHREAD)Key == ErrThread->ThreadKey.ThIDKey.ThreadID) 00171 { 00172 break; 00173 } 00174 break; 00175 } 00176 } 00177 ErrThread = NULL; 00178 } 00179 ExReleaseSpinLock(&IoepErrListLock, Irql); 00180 00181 EXIT(2, ("=%p\n", ErrThread)); 00182 return ErrThread; 00183 } //IoepFindErrThread

NTSTATUS IoepFireWMIEvent IN PERRINFO  ErrInfo,
IN PWSTR  InstanceName
 

Definition at line 612 of file ioerr.c.

References DBGPRINT, ENTER, ExAllocatePoolWithTag, EXIT, IoepGuid, IOETAG_WMIEVENT, IoWMIWriteEvent(), KeQuerySystemTime(), NonPagedPool, NTSTATUS(), NULL, and PROCNAME.

Referenced by IoErrTerminateErrLog().

00618 : 00619 This routine fires a WMI event notifying the availability of an error info. 00620 00621 Arguments: 00622 ErrInfo - points to the error info. 00623 InstanceName - points to the instance name string 00624 00625 Return Value: 00626 Success - returns STATUS_SUCCESS 00627 Failure - returns NT status code 00628 00629 --*/ 00630 { 00631 PROCNAME("IoepFireWMIEvent"); 00632 NTSTATUS status; 00633 00634 ENTER(2, ("(ErrInfo=%p,InstanceName=%S)\n", ErrInfo, InstanceName)); 00635 00636 if (ErrInfo != NULL) 00637 { 00638 ULONG NameLen, EventSize; 00639 PWNODE_SINGLE_INSTANCE event; 00640 00641 NameLen = wcslen(InstanceName)*sizeof(WCHAR) + sizeof(UNICODE_NULL); 00642 EventSize = sizeof(WNODE_SINGLE_INSTANCE) + NameLen + ErrInfo->Size; 00643 event = ExAllocatePoolWithTag(NonPagedPool, 00644 EventSize, 00645 IOETAG_WMIEVENT); 00646 if (event != NULL) 00647 { 00648 event->WnodeHeader.BufferSize = EventSize; 00649 event->WnodeHeader.ProviderId = 0; 00650 event->WnodeHeader.Guid = IoepGuid; 00651 event->WnodeHeader.Flags = WNODE_FLAG_SINGLE_INSTANCE | 00652 WNODE_FLAG_EVENT_ITEM; 00653 KeQuerySystemTime(&event->WnodeHeader.TimeStamp); 00654 event->OffsetInstanceName = sizeof(WNODE_SINGLE_INSTANCE); 00655 event->DataBlockOffset = sizeof(WNODE_SINGLE_INSTANCE) + NameLen; 00656 event->SizeDataBlock = ErrInfo->Size; 00657 RtlCopyMemory(&event->VariableData, InstanceName, NameLen); 00658 RtlCopyMemory(event->VariableData + NameLen, 00659 ErrInfo, 00660 ErrInfo->Size); 00661 status = IoWMIWriteEvent(event); 00662 } 00663 else 00664 { 00665 status = STATUS_INSUFFICIENT_RESOURCES; 00666 DBGPRINT(("failed to allocate WMI event node (len=%d)\n", 00667 EventSize)); 00668 } 00669 } 00670 else 00671 { 00672 status = STATUS_SUCCESS; 00673 } 00674 00675 EXIT(2, ("=%x\n", status)); 00676 return status; 00677 } //IoepFireWMIEvent

VOID IoepFreeErrStack IN PERRENTRY  ErrStack  ) 
 

Definition at line 414 of file ioerr.c.

References ASSERT, _errentry::DataBlk, ENTER, ExFreePool(), EXIT, IoepErrListLock, IoepGetNextErrEntry, NULL, PROCNAME, RtlFreeUnicodeString(), _errentry::slist, and _errentry::unicodeStr.

Referenced by IoErrTerminateErrLog().

00419 : 00420 This routine frees an error stack and the associated data blocks. 00421 00422 Arguments: 00423 ErrStack - points to the error stack to be freed 00424 00425 Return Value: 00426 None 00427 00428 --*/ 00429 { 00430 PROCNAME("IoepFreeErrStack"); 00431 PERRENTRY Err, ErrNext; 00432 KIRQL Irql; 00433 00434 ASSERT(ErrStack != NULL); 00435 ENTER(2, ("(ErrStack=%p)\n", ErrStack)); 00436 00437 ExAcquireSpinLock(&IoepErrListLock, &Irql); 00438 for (Err = ErrStack; Err != NULL; Err = ErrNext) 00439 { 00440 if (Err->DataBlk != NULL) 00441 { 00442 ExFreePool(Err->DataBlk); 00443 Err->DataBlk = NULL; 00444 } 00445 RtlFreeUnicodeString(&Err->unicodeStr); 00446 ErrNext = IoepGetNextErrEntry(Err); 00447 Err->slist.Next = NULL; 00448 ExFreePool(Err); 00449 } 00450 ExReleaseSpinLock(&IoepErrListLock, Irql); 00451 00452 EXIT(2, ("!\n")); 00453 } //IoepFreeErrStack

PERRCASEDB IoepGetErrCaseDB VOID   ) 
 

Definition at line 1200 of file ioerr.c.

References DBGPRINT, ENTER, ExAllocatePoolWithTag, ExFreePool(), EXIT, IoepErrCaseDB, IoepRegKeyStrIoErr, IOETAG_ERRCASEDB, IopGetRegistryValue(), L, _errcasedb::Length, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, PROCNAME, RtlInitUnicodeString(), and ZwCreateFile().

Referenced by IoepCatMsgArg(), IoepGetErrMessage(), IoepHandleErrCase(), IoErrFindErrCaseByID(), and IoErrMatchErrCase().

01205 : 01206 This routine checks if the ErrCase database has been read into memory. 01207 If it has, it returns the pointer to the error case database. Otherwise, 01208 it tries to read the database in. 01209 01210 Arguments: 01211 None 01212 01213 Return Value: 01214 Success - returns pointer to the error case database 01215 Failure - returns NULL 01216 01217 --*/ 01218 { 01219 PROCNAME("IoepGetErrCaseDB"); 01220 01221 PAGED_CODE(); 01222 ENTER(2, ("()\n")); 01223 01224 if (IoepErrCaseDB == NULL) 01225 { 01226 OBJECT_ATTRIBUTES ObjAttr; 01227 NTSTATUS status; 01228 HANDLE hReg, hFile; 01229 01230 InitializeObjectAttributes(&ObjAttr, 01231 &IoepRegKeyStrIoErr, 01232 OBJ_CASE_INSENSITIVE, 01233 NULL, 01234 NULL); 01235 status = ZwOpenKey(&hReg, KEY_READ, &ObjAttr); 01236 if (NT_SUCCESS(status)) 01237 { 01238 PKEY_VALUE_FULL_INFORMATION KeyValue; 01239 01240 status = IopGetRegistryValue(hReg, L"ErrCaseDB", &KeyValue); 01241 if (NT_SUCCESS(status)) 01242 { 01243 UNICODE_STRING unicodeStr; 01244 IO_STATUS_BLOCK IoStatusBlk; 01245 01246 RtlInitUnicodeString(&unicodeStr, 01247 (PWSTR)((PUCHAR)KeyValue + 01248 KeyValue->DataOffset)); 01249 InitializeObjectAttributes(&ObjAttr, 01250 &unicodeStr, 01251 OBJ_CASE_INSENSITIVE, 01252 NULL, 01253 NULL); 01254 status = ZwCreateFile(&hFile, 01255 FILE_READ_DATA, 01256 &ObjAttr, 01257 &IoStatusBlk, 01258 NULL, 01259 FILE_ATTRIBUTE_NORMAL, 01260 FILE_SHARE_READ, 01261 FILE_OPEN, 01262 FILE_NON_DIRECTORY_FILE | 01263 FILE_SEQUENTIAL_ONLY | 01264 FILE_SYNCHRONOUS_IO_NONALERT, 01265 NULL, 01266 0); 01267 01268 if (NT_SUCCESS(status) && 01269 (IoStatusBlk.Information == FILE_OPENED)) 01270 { 01271 ERRCASEDB DBHeader; 01272 01273 status = ZwReadFile(hFile, 01274 NULL, 01275 NULL, 01276 NULL, 01277 &IoStatusBlk, 01278 &DBHeader, 01279 sizeof(DBHeader), 01280 NULL, 01281 NULL); 01282 01283 if (NT_SUCCESS(status)) 01284 { 01285 IoepErrCaseDB = ExAllocatePoolWithTag(PagedPool, 01286 DBHeader.Length, 01287 IOETAG_ERRCASEDB); 01288 if (IoepErrCaseDB != NULL) 01289 { 01290 RtlCopyMemory(IoepErrCaseDB, 01291 &DBHeader, 01292 sizeof(DBHeader)); 01293 status = ZwReadFile(hFile, 01294 NULL, 01295 NULL, 01296 NULL, 01297 &IoStatusBlk, 01298 (PUCHAR)IoepErrCaseDB + 01299 sizeof(DBHeader), 01300 DBHeader.Length - 01301 sizeof(DBHeader), 01302 NULL, 01303 NULL); 01304 01305 if (!NT_SUCCESS(status)) 01306 { 01307 ExFreePool(IoepErrCaseDB); 01308 IoepErrCaseDB = NULL; 01309 DBGPRINT(("failed to read error case database (rc=%x)\n", 01310 status)); 01311 } 01312 } 01313 else 01314 { 01315 DBGPRINT(("failed to allocate storage for error case database (len=%d)\n", 01316 DBHeader.Length)); 01317 } 01318 } 01319 else 01320 { 01321 DBGPRINT(("failed to read database header (rc=%x)\n", 01322 status)); 01323 } 01324 ZwClose(hFile); 01325 } 01326 else 01327 { 01328 DBGPRINT(("failed to open error case database (rc=%x)\n", 01329 status)); 01330 } 01331 ExFreePool(KeyValue); 01332 } 01333 else 01334 { 01335 DBGPRINT(("failed to read registry value (rc=%x)\n", status)); 01336 } 01337 ZwClose(hReg); 01338 } 01339 else 01340 { 01341 DBGPRINT(("failed to open registry key (rc=%x)\n", status)); 01342 } 01343 } 01344 01345 EXIT(2, ("=%p\n", IoepErrCaseDB)); 01346 return IoepErrCaseDB; 01347 } //IoepGetErrCaseDB } //IoepGetErrCaseDB

NTSTATUS IoepGetErrMessage IN PMSGDATA  MsgData,
IN PERRINFO  ErrInfo,
OUT PUNICODE_STRING  unicodeMsg
 

Definition at line 936 of file ioerr.c.

References _errcasedb::DataBlkOffset, DBGPRINT, ENTER, ExAllocatePoolWithTag, EXIT, IoepCatMsgArg(), IoepGetErrCaseDB(), IoepUnicodeStringCatN(), IOETAG_MSGBUFF, L, MAX_MSG_LEN, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, PROCNAME, RtlAppendUnicodeToString(), RtlInitUnicodeString(), and STATUS_IOE_DATABASE_NOT_READY.

Referenced by IoepHandleErrCase().

00943 : 00944 This routine constructs the error message from the message method data. 00945 00946 Arguments: 00947 MsgData - points to the message method data 00948 ErrInfo - points to the error info 00949 unicodeMsg - points to the uninitialized unicode string message buffer 00950 00951 Return Value: 00952 Success - returns STATUS_SUCCESS 00953 Failure - returns NT status code 00954 00955 Note: 00956 This routine will allocate the actual string buffer of the unicode message. 00957 Therefore, it is the caller's responsibility to free the message buffer 00958 via RtlFreeUnicodeString. 00959 00960 --*/ 00961 { 00962 PROCNAME("IoepGetErrMessage"); 00963 NTSTATUS status = STATUS_SUCCESS; 00964 PERRCASEDB ErrCaseDB; 00965 00966 PAGED_CODE(); 00967 ENTER(2, ("(pMsgData=%p,ErrInfo=%p,pMsg=%p)\n", 00968 MsgData, ErrInfo, unicodeMsg)); 00969 00970 ErrCaseDB = IoepGetErrCaseDB(); 00971 if (ErrCaseDB != NULL) 00972 { 00973 PWSTR MsgTemplate, MsgBuff, pwstr; 00974 00975 MsgTemplate = (PWSTR)((ULONG_PTR)ErrCaseDB + 00976 ErrCaseDB->DataBlkOffset + 00977 MsgData->MsgTemplateOffset); 00978 00979 MsgBuff = ExAllocatePoolWithTag(PagedPool, 00980 sizeof(WCHAR)*MAX_MSG_LEN + 00981 sizeof(UNICODE_NULL), 00982 IOETAG_MSGBUFF); 00983 00984 if (MsgBuff != NULL) 00985 { 00986 MsgBuff[0] = L'\0'; 00987 RtlInitUnicodeString(unicodeMsg, MsgBuff); 00988 unicodeMsg->MaximumLength = sizeof(WCHAR)*MAX_MSG_LEN + 00989 sizeof(UNICODE_NULL); 00990 00991 while (NT_SUCCESS(status)) 00992 { 00993 pwstr = wcschr(MsgTemplate, L'%'); 00994 if (pwstr == NULL) 00995 { 00996 status = RtlAppendUnicodeToString(unicodeMsg, MsgTemplate); 00997 if (!NT_SUCCESS(status)) 00998 { 00999 DBGPRINT(("failed to append unicode string (rc=%x)\n", 01000 status)); 01001 } 01002 break; 01003 } 01004 else if ((pwstr[1] >= L'0') && (pwstr[1] <= L'9')) 01005 { 01006 ULONG ArgIndex; 01007 PWSTR pwstr2; 01008 01009 ArgIndex = wcstoul(&pwstr[1], &pwstr2, 10); 01010 status = IoepUnicodeStringCatN(unicodeMsg, 01011 MsgTemplate, 01012 pwstr - MsgTemplate); 01013 if (NT_SUCCESS(status)) 01014 { 01015 MsgTemplate = pwstr2; 01016 status = IoepCatMsgArg(unicodeMsg, 01017 &MsgData->Args[ArgIndex], 01018 ErrInfo); 01019 } 01020 } 01021 else 01022 { 01023 pwstr++; 01024 status = IoepUnicodeStringCatN(unicodeMsg, 01025 MsgTemplate, 01026 pwstr - MsgTemplate); 01027 if (NT_SUCCESS(status)) 01028 { 01029 MsgTemplate = pwstr; 01030 } 01031 } 01032 } 01033 } 01034 else 01035 { 01036 status = STATUS_INSUFFICIENT_RESOURCES; 01037 DBGPRINT(("failed to allocate message buffer\n")); 01038 } 01039 } 01040 else 01041 { 01042 status = STATUS_IOE_DATABASE_NOT_READY; 01043 DBGPRINT(("error case database not ready\n")); 01044 } 01045 01046 EXIT(2, ("=%x(Msg=%S)\n", 01047 status, unicodeMsg->Buffer? unicodeMsg->Buffer: L"")); 01048 return status; 01049 } //IoepGetErrMessage

NTSTATUS IoepHandleErrCase IN PERRINFO  ErrInfo,
IN PERRCASE  ErrCase,
IN ULONG  Method,
OUT PUNICODE_STRING unicodeMsg  OPTIONAL
 

Definition at line 680 of file ioerr.c.

References _errcasedb::DataBlkOffset, DBGPRINT, ENTER, ExAllocatePoolWithTag, EXIT, IOEMETHOD_ANY, IOEMETHOD_HANDLER, IOEMETHOD_LONGMSG, IOEMETHOD_SHORTMSG, IoepFindErrHandler(), IoepGetErrCaseDB(), IoepGetErrMessage(), IOETAG_DATAWSTR, IoRaiseInformationalHardError(), _method::MethodDataOffset, _method::MethodType, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, PERRHANDLER, PROCNAME, RtlFreeUnicodeString(), RtlInitUnicodeString(), STATUS_IOE_DATABASE_NOT_READY, and STATUS_IOE_MESSAGE.

Referenced by IoErrGetLongErrMessage(), IoErrGetShortErrMessage(), and IoErrHandleErrCase().

00688 : 00689 This routine handles an error case by executing the resolution method. 00690 00691 Arguments: 00692 ErrInfo - points to the error info 00693 ErrCase - points to the error case 00694 Method - specifying what method to use to handle the error case 00695 unicodeMsg - point to unicodeStr to receive the error message 00696 00697 Return Value: 00698 Success - returns STATUS_SUCCESS 00699 Failure - returns NT status code 00700 00701 --*/ 00702 { 00703 PROCNAME("IoepHandleErrCase"); 00704 NTSTATUS status; 00705 PERRCASEDB ErrCaseDB; 00706 00707 PAGED_CODE(); 00708 ENTER(2, ("(ErrInfo=%p,ErrCase=%p,Method=%x,unicodeMsg=%p)\n", 00709 ErrInfo, ErrCase, Method, unicodeMsg)); 00710 00711 ErrCaseDB = IoepGetErrCaseDB(); 00712 if (ErrCaseDB != NULL) 00713 { 00714 PMETHOD MethodTable; 00715 ULONG i; 00716 PVOID MethodData; 00717 UNICODE_STRING unicodeStr; 00718 PERRHANDLER ErrHandler; 00719 PWSTR MsgTemplate; 00720 00721 MethodTable = (PMETHOD)((ULONG_PTR)ErrCaseDB + 00722 ErrCaseDB->DataBlkOffset + 00723 ErrCase->MethodOffset); 00724 00725 for (i = 0, status = STATUS_NOT_FOUND; 00726 (status == STATUS_NOT_FOUND) && (i < ErrCase->NumMethods); 00727 ++i) 00728 { 00729 if ((Method != IOEMETHOD_ANY) && 00730 (Method != MethodTable[i].MethodType)) 00731 { 00732 continue; 00733 } 00734 00735 MethodData = (PVOID)((ULONG_PTR)ErrCaseDB + 00736 ErrCaseDB->DataBlkOffset + 00737 MethodTable[i].MethodDataOffset); 00738 00739 switch (MethodTable[i].MethodType) 00740 { 00741 case IOEMETHOD_LONGMSG: 00742 status = IoepGetErrMessage((PMSGDATA)MethodData, 00743 ErrInfo, 00744 unicodeMsg? unicodeMsg: 00745 &unicodeStr); 00746 00747 if (NT_SUCCESS(status) && (unicodeMsg == NULL)) 00748 { 00749 IoRaiseInformationalHardError(STATUS_IOE_MESSAGE, 00750 &unicodeStr, 00751 NULL); 00752 RtlFreeUnicodeString(&unicodeStr); 00753 } 00754 break; 00755 00756 case IOEMETHOD_SHORTMSG: 00757 MsgTemplate = 00758 (PWSTR)((ULONG_PTR)ErrCaseDB + 00759 ErrCaseDB->DataBlkOffset + 00760 ((PMSGDATA)MethodData)->MsgTemplateOffset); 00761 00762 if (unicodeMsg == NULL) 00763 { 00764 RtlInitUnicodeString(&unicodeStr, MsgTemplate); 00765 IoRaiseInformationalHardError(STATUS_IOE_MESSAGE, 00766 &unicodeStr, 00767 NULL); 00768 status = STATUS_SUCCESS; 00769 } 00770 else 00771 { 00772 ULONG len; 00773 PWSTR pwstr; 00774 00775 len = wcslen(MsgTemplate)*sizeof(WCHAR) + 00776 sizeof(UNICODE_NULL); 00777 pwstr = ExAllocatePoolWithTag(PagedPool, 00778 len, 00779 IOETAG_DATAWSTR); 00780 if (pwstr != NULL) 00781 { 00782 RtlCopyMemory(pwstr, MsgTemplate, len); 00783 RtlInitUnicodeString(unicodeMsg, pwstr); 00784 status = STATUS_SUCCESS; 00785 } 00786 else 00787 { 00788 status = STATUS_INSUFFICIENT_RESOURCES; 00789 DBGPRINT(("failed to allocate short message buffer (len=%d)\n", 00790 len)); 00791 } 00792 } 00793 break; 00794 00795 case IOEMETHOD_HANDLER: 00796 ErrHandler = IoepFindErrHandler( 00797 &((PHANDLERDATA)MethodData)->ComponentGuid, 00798 ((PHANDLERDATA)MethodData)->HandlerIndex); 00799 00800 if (ErrHandler != NULL) 00801 { 00802 status = ErrHandler(ErrInfo, 00803 ((PHANDLERDATA)MethodData)->Param); 00804 } 00805 break; 00806 00807 default: 00808 DBGPRINT(("invalid method type %d\n", 00809 MethodTable[i].MethodType)); 00810 } 00811 } 00812 } 00813 else 00814 { 00815 status = STATUS_IOE_DATABASE_NOT_READY; 00816 DBGPRINT(("error case database not ready\n")); 00817 } 00818 00819 EXIT(2, ("=%x\n", status)); 00820 return status; 00821 } //IoepHandleErrCase

HANDLE IoepInitErrLog IN ULONG  KeyType,
IN PVOID  Key,
IN ULONG  ulFlags
 

Definition at line 39 of file ioerr.c.

References ASSERT, DBGPRINT, ENTER, _errlog::ErrInfo, _errthread::ErrLogListHead, _errlog::ErrStack, _errlog::ErrThread, ExAllocatePoolWithTag, ExFreePool(), ExInterlockedInsertHeadList(), EXIT, IoepErrListLock, IoepFindErrThread(), IoepNewErrThread(), IOETAG_ERRLOG, Key, _errlog::list, LOGF_INITMASK, NonPagedPool, NULL, PROCNAME, SIG_ERRLOG, _errlog::Signature, and _errlog::ulFlags.

Referenced by IoErrInitErrLogByIrp(), and IoErrInitErrLogByThreadID().

00046 : 00047 This routine initializes an error logging session with the specified key. 00048 00049 Arguments: 00050 KeyType - specifies the key type 00051 Key - points to the key 00052 ulFlags - log session flags 00053 00054 Return Value: 00055 Success - returns the newly created error log handle. 00056 Failure - returns NULL. 00057 00058 --*/ 00059 { 00060 PROCNAME("IoepInitErrLog"); 00061 PERRLOG ErrLog; 00062 00063 ASSERT(Key != NULL); 00064 ASSERT(ulFlags & ~LOGF_INITMASK == 0); 00065 ENTER(2, ("(KeyType=%x,Key=%p,ulFlags=%x)\n", KeyType, Key, ulFlags)); 00066 00067 ErrLog = ExAllocatePoolWithTag(NonPagedPool, 00068 sizeof(ERRLOG), 00069 IOETAG_ERRLOG); 00070 00071 if (ErrLog != NULL) 00072 { 00073 PERRTHREAD ErrThread; 00074 00075 ErrThread = IoepFindErrThread(KeyType, Key); 00076 if (ErrThread == NULL) 00077 { 00078 ErrThread = IoepNewErrThread(KeyType, Key); 00079 } 00080 00081 if (ErrThread != NULL) 00082 { 00083 ErrLog->Signature = SIG_ERRLOG; 00084 ErrLog->ulFlags = ulFlags & LOGF_INITMASK; 00085 ErrLog->ErrThread = ErrThread; 00086 ErrLog->ErrStack.Next = NULL; 00087 ErrLog->ErrInfo = NULL; 00088 ExInterlockedInsertHeadList(&ErrThread->ErrLogListHead, 00089 &ErrLog->list, 00090 &IoepErrListLock); 00091 } 00092 else 00093 { 00094 ExFreePool(ErrLog); 00095 ErrLog = NULL; 00096 } 00097 } 00098 else 00099 { 00100 DBGPRINT(("failed to allocate new error log\n")); 00101 } 00102 00103 EXIT(2, ("=%p\n", ErrLog)); 00104 return ErrLog; 00105 } //IoepInitErrLog

VOID IoepLogErr IN ULONG  KeyType,
IN PVOID  Key,
IN CONST GUID *  ComponentGuid,
IN ULONG  ErrCode,
IN PWSTR TextData  OPTIONAL,
IN ULONG  DataBlkType,
IN ULONG DataBlkLen  OPTIONAL,
IN PVOID DataBlock  OPTIONAL,
IN CONST GUID *MofGuid  OPTIONAL
 

Definition at line 255 of file ioerr.c.

References ASSERT, _errid::ComponentGuid, _errentry::DataBlk, _errentry::DataBlkLen, _errentry::DataBlkType, DBGPRINT, ENTER, _errid::ErrCode, ERRENTRY, _errentry::ErrID, _errthread::ErrLogListHead, _errlog::ErrStack, ExAllocatePoolWithTag, ExFreePool(), EXIT, FALSE, IOEDATA_MAX, IOEDATA_NONE, IoepErrListLock, IoepFindErrThread(), IOETAG_DATABLOCK, IOETAG_DATATEXT, IOETAG_ERRENTRY, Key, L, _errentry::MofGuid, NonPagedPool, NULL, PROCNAME, RtlInitUnicodeString(), _errentry::slist, TRUE, and _errentry::unicodeStr.

Referenced by IoErrLogErrByIrp(), and IoErrLogErrByThreadID().

00268 : 00269 This routine logs the error data to the error log session identified by 00270 the given key. 00271 00272 Arguments: 00273 KeyType - specifies the type of key. 00274 Key - points to the key that is used to locate the logging session. 00275 ComponentGuid - points to the component GUID of the caller 00276 ErrCode - unique error code 00277 TextData - points to an optional WSTR of text data 00278 DataBlkType - data type of the data block 00279 DataBlkLen - length of the data block 00280 DataBlock - points to the data block 00281 MofGuid - points to the MOF GUID of the data block if applicable 00282 00283 Return Value: 00284 None 00285 00286 --*/ 00287 { 00288 PROCNAME("IoepLogErr"); 00289 PERRTHREAD ErrThread; 00290 00291 ASSERT(Key != NULL); 00292 ASSERT(ComponentGuid != NULL); 00293 ASSERT((DataBlkType == IOEDATA_NONE) || 00294 (DataBlkLen > 0) && (DataBlock != NULL)); 00295 ASSERT(DataBlkType <= IOEDATA_MAX); 00296 ENTER(2, ("(KeyType=%x,Key=%p,pGuid=%p,ErrCode=%x,Text=%S,Type=%x,Len=%d,DataBlk=%p,MofGuid=%p)\n", 00297 KeyType, Key, ComponentGuid, ErrCode, TextData? TextData: L"", 00298 DataBlkType, DataBlkLen, DataBlock, MofGuid)); 00299 00300 ErrThread = IoepFindErrThread(KeyType, Key); 00301 if (ErrThread != NULL) 00302 { 00303 PERRENTRY Err; 00304 00305 ASSERT(!IsListEmpty(&ErrThread->ErrLogListHead)); 00306 Err = ExAllocatePoolWithTag(NonPagedPool, 00307 sizeof(ERRENTRY), 00308 IOETAG_ERRENTRY); 00309 00310 if (Err != NULL) 00311 { 00312 BOOLEAN fOK = TRUE; 00313 PVOID Data = NULL; 00314 PWSTR pwstr = NULL; 00315 00316 RtlZeroMemory(Err, sizeof(ERRENTRY)); 00317 if (DataBlkType != IOEDATA_NONE) 00318 { 00319 Data = ExAllocatePoolWithTag(NonPagedPool, 00320 DataBlkLen, 00321 IOETAG_DATABLOCK); 00322 00323 if (Data != NULL) 00324 { 00325 RtlCopyMemory(Data, DataBlock, DataBlkLen); 00326 } 00327 else 00328 { 00329 fOK = FALSE; 00330 DBGPRINT(("failed to allocate data block (len=%d)\n", 00331 DataBlkLen)); 00332 } 00333 } 00334 else 00335 { 00336 // 00337 // Make sure DataLen does not have garbage. 00338 // 00339 DataBlkLen = 0; 00340 } 00341 00342 if (TextData != NULL) 00343 { 00344 ULONG len; 00345 00346 len = wcslen(TextData)*sizeof(WCHAR) + sizeof(UNICODE_NULL); 00347 pwstr = ExAllocatePoolWithTag(NonPagedPool, 00348 len, 00349 IOETAG_DATATEXT); 00350 00351 if (pwstr != NULL) 00352 { 00353 RtlCopyMemory(pwstr, TextData, len); 00354 RtlInitUnicodeString(&Err->unicodeStr, pwstr); 00355 } 00356 else 00357 { 00358 fOK = FALSE; 00359 DBGPRINT(("failed to allocate text data (len=%d)\n", 00360 len)); 00361 } 00362 } 00363 00364 if (fOK) 00365 { 00366 PERRLOG ErrLog; 00367 KIRQL Irql; 00368 00369 Err->ErrID.ComponentGuid = *ComponentGuid; 00370 Err->ErrID.ErrCode = ErrCode; 00371 Err->DataBlkType = DataBlkType; 00372 Err->DataBlkLen = DataBlkLen; 00373 Err->DataBlk = Data; 00374 if (MofGuid != NULL) 00375 { 00376 Err->MofGuid = *MofGuid; 00377 } 00378 00379 ExAcquireSpinLock(&IoepErrListLock, &Irql); 00380 ErrLog = CONTAINING_RECORD(ErrThread->ErrLogListHead.Flink, 00381 ERRLOG, 00382 list); 00383 PushEntryList(&ErrLog->ErrStack, &Err->slist); 00384 ExReleaseSpinLock(&IoepErrListLock, Irql); 00385 } 00386 else 00387 { 00388 if (Data != NULL) 00389 { 00390 ExFreePool(Data); 00391 } 00392 if (pwstr != NULL) 00393 { 00394 ExFreePool(pwstr); 00395 } 00396 ExFreePool(Err); 00397 } 00398 } 00399 else 00400 { 00401 DBGPRINT(("failed to allocate error entry\n")); 00402 } 00403 } 00404 else 00405 { 00406 DBGPRINT(("failed to find associated error thread (Type=%x,Key=%p)\n", 00407 KeyType, Key)); 00408 } 00409 00410 EXIT(2, ("!\n")); 00411 } //IoepLogErr

BOOLEAN IoepMatchErrIDPath IN PERRINFO  ErrInfo,
IN PERRID  ErrIDPath,
IN ULONG  NumErrIDs
 

Definition at line 862 of file ioerr.c.

References ENTER, EXIT, FALSE, PAGED_CODE, PROCNAME, and TRUE.

Referenced by IoErrMatchErrCase().

00869 : 00870 This routine compares the error ID paths for a match. 00871 00872 Arguments: 00873 ErrInfo - points to the error info buffer 00874 ErrIDPath - points to the error ID path of the error case 00875 NumErrIDs - number of error IDs in the path 00876 00877 Return Value: 00878 Success - returns TRUE: matched 00879 Failure - returns FALSE: no match 00880 00881 --*/ 00882 { 00883 PROCNAME("IoepMatchErrIDPath"); 00884 BOOLEAN rc = TRUE; 00885 BOOLEAN fWildCard = FALSE; 00886 ULONG i, j; 00887 00888 PAGED_CODE(); 00889 ENTER(2, ("(ErrInfo=%p,pErrID=%p,NumIDs=%d)\n", 00890 ErrInfo, ErrIDPath, NumErrIDs)); 00891 00892 for (i = j = 0; (i < NumErrIDs) && (j < ErrInfo->NumErrEntries);) 00893 { 00894 if (ErrIDPath[i].ErrCode == 0) 00895 { 00896 fWildCard = TRUE; 00897 i++; 00898 } 00899 else if (RtlEqualMemory(&ErrIDPath[i].ComponentGuid, 00900 &ErrInfo->ErrEntries[j].ErrID.ComponentGuid, 00901 sizeof(GUID)) && 00902 (ErrIDPath[i].ErrCode == ErrInfo->ErrEntries[j].ErrID.ErrCode)) 00903 { 00904 i++; 00905 j++; 00906 fWildCard = FALSE; 00907 } 00908 else if (fWildCard) 00909 { 00910 j++; 00911 } 00912 else 00913 { 00914 rc = FALSE; 00915 break; 00916 } 00917 } 00918 00919 if ((rc == TRUE) && (i < NumErrIDs)) 00920 { 00921 // 00922 // The database ID path is longer than the error stack ID path. 00923 // This is not a good match, so let's move on to find another match. 00924 // However, the reverse is OK though (i.e. error stack ID path is 00925 // longer than the database ID path). In this case, the database 00926 // ID path has an implicit wild card at the end. 00927 // 00928 rc = FALSE; 00929 } 00930 00931 EXIT(2, ("=%x\n", rc)); 00932 return rc; 00933 } //IoepMatchErrIDPath

PERRTHREAD IoepNewErrThread IN ULONG  KeyType,
IN PVOID  Key
 

Definition at line 186 of file ioerr.c.

References DBGPRINT, _IO_STACK_LOCATION::DeviceObject, ENTER, _errthread::ErrLogListHead, ExAllocatePoolWithTag, ExInterlockedInsertHeadList(), EXIT, IoepErrListLock, IoepErrThreadListHead, IOETAG_ERRTHREAD, IoGetCurrentIrpStackLocation, Key, _errthread::list, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NonPagedPool, NULL, _IO_STACK_LOCATION::Parameters, PROCNAME, _errthread::ThreadKey, THREADKEY_IRP, THREADKEY_THREADID, and _errthread::ThreadKeyType.

Referenced by IoepInitErrLog().

00192 : 00193 This routine creates a new error thread with a given key. 00194 00195 Arguments: 00196 KeyType - specifies the type of key. 00197 Key - points to the key that is used to create the new logging session. 00198 00199 Return Value: 00200 Success - returns the error thread handle created. 00201 Failure - returns NULL. 00202 00203 --*/ 00204 { 00205 PROCNAME("IoepNewErrThread"); 00206 PERRTHREAD ErrThread; 00207 00208 ENTER(2, ("(KeyType=%x,Key=%p)\n", KeyType, Key)); 00209 00210 ErrThread = ExAllocatePoolWithTag(NonPagedPool, 00211 sizeof(ERRTHREAD), 00212 IOETAG_ERRTHREAD); 00213 00214 if (ErrThread != NULL) 00215 { 00216 PIO_STACK_LOCATION IrpSp; 00217 00218 InitializeListHead(&ErrThread->ErrLogListHead); 00219 ErrThread->ThreadKeyType = KeyType; 00220 00221 switch (KeyType) 00222 { 00223 case THREADKEY_IRP: 00224 IrpSp = IoGetCurrentIrpStackLocation((PIRP)Key); 00225 ErrThread->ThreadKey.IrpKey.Irp = (PIRP)Key; 00226 ErrThread->ThreadKey.IrpKey.MajorFunction = 00227 IrpSp->MajorFunction; 00228 ErrThread->ThreadKey.IrpKey.MinorFunction = 00229 IrpSp->MinorFunction; 00230 RtlCopyMemory(ErrThread->ThreadKey.IrpKey.Arguments, 00231 &IrpSp->Parameters.Others, 00232 sizeof(PVOID)*4); 00233 ErrThread->ThreadKey.IrpKey.TargetDevice = 00234 IopDbgGetLowestDevice(IrpSp->DeviceObject); 00235 break; 00236 00237 case THREADKEY_THREADID: 00238 ErrThread->ThreadKey.ThIDKey.ThreadID = (PKTHREAD)Key; 00239 break; 00240 } 00241 ExInterlockedInsertHeadList(&IoepErrThreadListHead, 00242 &ErrThread->list, 00243 &IoepErrListLock); 00244 } 00245 else 00246 { 00247 DBGPRINT(("failed to allocate error thread\n")); 00248 } 00249 00250 EXIT(2, ("=%p\n", ErrThread)); 00251 return ErrThread; 00252 } //IoepNewErrThread

NTSTATUS IoepUnicodeStringCatN IN OUT PUNICODE_STRING  unicodeStr,
IN PWSTR  pwstr,
IN ULONG  len
 

Definition at line 1155 of file ioerr.c.

References DBGPRINT, ENTER, EXIT, L, NTSTATUS(), PAGED_CODE, PROCNAME, and USHORT.

Referenced by IoepGetErrMessage().

01162 : 01163 This routine appends the wchar string to the unicode string if there is 01164 enough space. Otherwise, STATUS_BUFFER_TOO_SMALL is returned. 01165 01166 Arguments: 01167 unicodeStr - points to the target unicode string 01168 pwstr - points to the wchar string 01169 len - length of wstr in bytes to append 01170 01171 Return Value: 01172 Success - returns STATUS_SUCCESS 01173 Failure - returns NT status code 01174 01175 --*/ 01176 { 01177 PROCNAME("IoepUnicodeStringCatN"); 01178 NTSTATUS status = STATUS_SUCCESS; 01179 01180 PAGED_CODE(); 01181 ENTER(2, ("(Msg=%S,Str=%S,Len=%d)\n", unicodeStr->Buffer, pwstr, len)); 01182 01183 if (len < (ULONG)(unicodeStr->MaximumLength - unicodeStr->Length)) 01184 { 01185 wcsncpy(unicodeStr->Buffer, pwstr, len/sizeof(WCHAR)); 01186 unicodeStr->Length += (USHORT)len; 01187 unicodeStr->Buffer[len/sizeof(WCHAR)] = L'\0'; 01188 } 01189 else 01190 { 01191 status = STATUS_BUFFER_TOO_SMALL; 01192 DBGPRINT(("unicode string too small\n")); 01193 } 01194 01195 EXIT(2, ("=%x(Msg=%S)\n", status, unicodeStr->Buffer)); 01196 return status; 01197 } //IoepUnicodeStringCatN


Generated on Sat May 15 19:44:17 2004 for test by doxygen 1.3.7