Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
8.5 KiB

  1. #include <windows.h>
  2. #include <rpc.h>
  3. #include <tchar.h>
  4. #include "faxutil.h"
  5. #ifdef DEBUG
  6. VOID
  7. DumpRPCExtendedStatus ()
  8. /*++
  9. Routine Description:
  10. Dumps the extended RPC error status list to the debug console.
  11. This function only works in debug builds.
  12. To enable RPC extended status on the machine do the following:
  13. 1. run mmc.exe
  14. 2. Goto File | Add/Remove Snap-in...
  15. 3. Press "Add..." button
  16. 4. Select "Group Policy" and Press "Add"
  17. 5. Select "Local Computer" and press "Finish"
  18. 6. Press "Close"
  19. 7. Press "Ok"
  20. 8. Expand Local Computer Policy | Computer Configuration | Administrative Templates | System |
  21. Remote Procedure Call
  22. 9. Select the properties of "Propagation of Extended Error Information"
  23. 10. Select "Enabled"
  24. 11. In the "Propagation of Extended Error Information" combo-box, select "On".
  25. 12. In the "...Exceptions" edit-box, leave the text empty.
  26. 13. Press "Ok".
  27. 14. Close MMC (no need to save anything).
  28. Arguments:
  29. None.
  30. Return Value:
  31. None.
  32. Remarks:
  33. This function should be called as soon as an error / exception
  34. is returned from calling an RPC function.
  35. --*/
  36. {
  37. DEBUG_FUNCTION_NAME(TEXT("DumpRPCExtendedStatus"));
  38. typedef RPC_STATUS (RPC_ENTRY *PRPCERRORSTARTENUMERATION) (RPC_ERROR_ENUM_HANDLE *);
  39. typedef RPC_STATUS (RPC_ENTRY *PRPCERRORGETNEXTRECORD) (RPC_ERROR_ENUM_HANDLE *, BOOL, RPC_EXTENDED_ERROR_INFO *);
  40. typedef RPC_STATUS (RPC_ENTRY *PRPCERRORENDENUMERATION) (RPC_ERROR_ENUM_HANDLE *);
  41. PRPCERRORSTARTENUMERATION pfRpcErrorStartEnumeration = NULL;
  42. PRPCERRORGETNEXTRECORD pfRpcErrorGetNextRecord = NULL;
  43. PRPCERRORENDENUMERATION pfRpcErrorEndEnumeration = NULL;
  44. HMODULE hMod = NULL;
  45. if (!IsWinXPOS())
  46. {
  47. //
  48. // RPC Extended errors are not supported in down-level clients
  49. //
  50. return;
  51. }
  52. hMod = LoadLibrary (TEXT("rpcrt4.dll"));
  53. if (!hMod)
  54. {
  55. DebugPrintEx(DEBUG_ERR, _T("LoadLibrary(rpcrt4.dll) failed with %ld"), GetLastError ());
  56. return;
  57. }
  58. pfRpcErrorStartEnumeration = (PRPCERRORSTARTENUMERATION)GetProcAddress (hMod, "RpcErrorStartEnumeration");
  59. pfRpcErrorGetNextRecord = (PRPCERRORGETNEXTRECORD) GetProcAddress (hMod, "RpcErrorGetNextRecord");
  60. pfRpcErrorEndEnumeration = (PRPCERRORENDENUMERATION) GetProcAddress (hMod, "RpcErrorEndEnumeration");
  61. if (!pfRpcErrorStartEnumeration ||
  62. !pfRpcErrorGetNextRecord ||
  63. !pfRpcErrorEndEnumeration)
  64. {
  65. DebugPrintEx(DEBUG_ERR, _T("Can't link with rpcrt4.dll - failed with %ld"), GetLastError ());
  66. FreeLibrary (hMod);
  67. return;
  68. }
  69. RPC_STATUS Status2;
  70. RPC_ERROR_ENUM_HANDLE EnumHandle;
  71. Status2 = pfRpcErrorStartEnumeration(&EnumHandle);
  72. if (Status2 == RPC_S_ENTRY_NOT_FOUND)
  73. {
  74. DebugPrintEx(DEBUG_ERR, _T("RPC_S_ENTRY_NOT_FOUND returned from RpcErrorStartEnumeration."));
  75. FreeLibrary (hMod);
  76. return;
  77. }
  78. else if (Status2 != RPC_S_OK)
  79. {
  80. DebugPrintEx(DEBUG_ERR, _T("Couldn't get EEInfo: %d"), Status2);
  81. FreeLibrary (hMod);
  82. return;
  83. }
  84. else
  85. {
  86. RPC_EXTENDED_ERROR_INFO ErrorInfo;
  87. BOOL Result;
  88. BOOL CopyStrings = TRUE;
  89. BOOL fUseFileTime = TRUE;
  90. SYSTEMTIME *SystemTimeToUse;
  91. SYSTEMTIME SystemTimeBuffer;
  92. while (Status2 == RPC_S_OK)
  93. {
  94. ErrorInfo.Version = RPC_EEINFO_VERSION;
  95. ErrorInfo.Flags = 0;
  96. ErrorInfo.NumberOfParameters = 4;
  97. if (fUseFileTime)
  98. {
  99. ErrorInfo.Flags |= EEInfoUseFileTime;
  100. }
  101. Status2 = pfRpcErrorGetNextRecord(&EnumHandle, CopyStrings, &ErrorInfo);
  102. if (Status2 == RPC_S_ENTRY_NOT_FOUND)
  103. {
  104. break;
  105. }
  106. else if (Status2 != RPC_S_OK)
  107. {
  108. DebugPrintEx(DEBUG_ERR, _T("Couldn't finish enumeration: %d"), Status2);
  109. break;
  110. }
  111. else
  112. {
  113. int i;
  114. if (ErrorInfo.ComputerName)
  115. {
  116. DebugPrintEx(DEBUG_MSG, _T("ComputerName is %s"), ErrorInfo.ComputerName);
  117. if (CopyStrings)
  118. {
  119. Result = HeapFree(GetProcessHeap(), 0, ErrorInfo.ComputerName);
  120. Assert(Result);
  121. }
  122. }
  123. DebugPrintEx(DEBUG_MSG, _T("ProcessID is %d"), ErrorInfo.ProcessID);
  124. if (fUseFileTime)
  125. {
  126. Result = FileTimeToSystemTime(&ErrorInfo.u.FileTime,
  127. &SystemTimeBuffer);
  128. Assert(Result);
  129. SystemTimeToUse = &SystemTimeBuffer;
  130. }
  131. else
  132. {
  133. SystemTimeToUse = &ErrorInfo.u.SystemTime;
  134. }
  135. DebugPrintEx(DEBUG_MSG, _T("System Time is: %d/%d/%d %d:%d:%d:%d"),
  136. SystemTimeToUse->wMonth,
  137. SystemTimeToUse->wDay,
  138. SystemTimeToUse->wYear,
  139. SystemTimeToUse->wHour,
  140. SystemTimeToUse->wMinute,
  141. SystemTimeToUse->wSecond,
  142. SystemTimeToUse->wMilliseconds);
  143. DebugPrintEx(DEBUG_MSG, _T("Generating component is %d"), ErrorInfo.GeneratingComponent);
  144. DebugPrintEx(DEBUG_MSG, _T("Status is %d"), ErrorInfo.Status);
  145. DebugPrintEx(DEBUG_MSG, _T("Detection location is %d"), (int)ErrorInfo.DetectionLocation);
  146. DebugPrintEx(DEBUG_MSG, _T("Flags is %d"), ErrorInfo.Flags);
  147. DebugPrintEx(DEBUG_MSG, _T("NumberOfParameters is %d"), ErrorInfo.NumberOfParameters);
  148. for (i = 0; i < ErrorInfo.NumberOfParameters; i ++)
  149. {
  150. switch(ErrorInfo.Parameters[i].ParameterType)
  151. {
  152. case eeptAnsiString:
  153. DebugPrintEx(DEBUG_MSG, _T("Ansi string: %S"), ErrorInfo.Parameters[i].u.AnsiString);
  154. if (CopyStrings)
  155. {
  156. Result = HeapFree(GetProcessHeap(), 0,
  157. ErrorInfo.Parameters[i].u.AnsiString);
  158. Assert(Result);
  159. }
  160. break;
  161. case eeptUnicodeString:
  162. DebugPrintEx(DEBUG_MSG, _T("Unicode string: %s"), ErrorInfo.Parameters[i].u.UnicodeString);
  163. if (CopyStrings)
  164. {
  165. Result = HeapFree(GetProcessHeap(), 0,
  166. ErrorInfo.Parameters[i].u.UnicodeString);
  167. Assert(Result);
  168. }
  169. break;
  170. case eeptLongVal:
  171. DebugPrintEx(DEBUG_MSG, _T("Long val: %d"), ErrorInfo.Parameters[i].u.LVal);
  172. break;
  173. case eeptShortVal:
  174. DebugPrintEx(DEBUG_MSG, _T("Short val: %d"), (int)ErrorInfo.Parameters[i].u.SVal);
  175. break;
  176. case eeptPointerVal:
  177. DebugPrintEx(DEBUG_MSG, _T("Pointer val: %d"), ErrorInfo.Parameters[i].u.PVal);
  178. break;
  179. case eeptNone:
  180. DebugPrintEx(DEBUG_MSG, _T("Truncated"));
  181. break;
  182. default:
  183. DebugPrintEx(DEBUG_MSG, _T("Invalid type: %d"), ErrorInfo.Parameters[i].ParameterType);
  184. }
  185. }
  186. }
  187. }
  188. pfRpcErrorEndEnumeration(&EnumHandle);
  189. }
  190. FreeLibrary (hMod);
  191. } // DumpRPCExtendedStatus
  192. #else // ifdef DEUBG
  193. VOID
  194. DumpRPCExtendedStatus ()
  195. {
  196. }
  197. #endif // ifdef DEBUG