Source code of Windows XP (NT5)
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.

401 lines
13 KiB

  1. /*---------------------------------------------------------------------------
  2. File: ErrDct.cpp
  3. Comments: TError derived class for OnePoint Domain Administrator messages
  4. (c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved
  5. Proprietary and confidential to Mission Critical Software, Inc.
  6. REVISION LOG ENTRY
  7. Revision By: Christy Boles
  8. Revised on 02/18/99 11:34:16
  9. ---------------------------------------------------------------------------
  10. */
  11. #ifdef USE_STDAFX
  12. #include "stdafx.h"
  13. #else
  14. #include <windows.h>
  15. #endif
  16. #include "ErrDct.hpp"
  17. #include "AdsErr.h"
  18. #define TERR_MAX_MSG_LEN (2000)
  19. // Recursively walk through a path, trying to create the directories at each level
  20. DWORD // ret - 0 if successful (directories created\already existed), OS return code otherwise
  21. DirectoryCreateR(
  22. WCHAR const * dirToCreate // in-directory to create (full path or UNC)
  23. )
  24. {
  25. WCHAR * c;
  26. WCHAR * end;
  27. BOOL error = FALSE;
  28. DWORD rcOs;
  29. WCHAR dirName[MAX_PATH+1];
  30. BOOL isUNC = FALSE;
  31. BOOL skipShareName = FALSE;
  32. if ( !dirName )
  33. return ERROR_INVALID_PARAMETER;
  34. safecopy(dirName,dirToCreate);
  35. // Note: if the string is empty, that's ok - we will catch it when we don't see C:\ or C$\ below
  36. // walk through the string, and try to create at each step along the way
  37. do { // once
  38. c = dirName;
  39. end = dirName + UStrLen(dirName);
  40. // skip computer-name if UNC
  41. if ( *c == L'\\' && *(c + 1) == L'\\' )
  42. {
  43. isUNC = TRUE;
  44. for ( c=c+2 ; *c && *c != L'\\' ; c++ )
  45. ;
  46. if ( ! *c )
  47. {
  48. error = TRUE;
  49. rcOs = ERROR_INVALID_PARAMETER;
  50. break;
  51. }
  52. c++;
  53. }
  54. // skip C:\ or C$\.
  55. if ( *(c) && ( *(c+1)==L'$' || *(c+1)==L':' ) && *(c+2)==L'\\' )
  56. {
  57. c = c + 3;
  58. if ( c == end ) // They put in the root directory for some volume
  59. break;
  60. }
  61. else
  62. {
  63. if ( isUNC )
  64. {
  65. skipShareName = TRUE;
  66. }
  67. else
  68. {
  69. rcOs = ERROR_INVALID_PARAMETER;
  70. error = TRUE;
  71. break;
  72. }
  73. }
  74. // scan through the string looking for '\'
  75. for ( ; c <= end ; c++ )
  76. {
  77. if ( !*c || *c == L'\\' )
  78. {
  79. if ( skipShareName )
  80. {
  81. skipShareName = FALSE;
  82. continue;
  83. }
  84. // try to create at this level
  85. *c = L'\0';
  86. if ( ! CreateDirectory(dirName,NULL) )
  87. {
  88. rcOs = GetLastError();
  89. switch ( rcOs )
  90. {
  91. case 0:
  92. case ERROR_ALREADY_EXISTS:
  93. break;
  94. default:
  95. error = TRUE;
  96. }
  97. }
  98. if (c != end )
  99. *c = L'\\';
  100. if ( error )
  101. break;
  102. }
  103. }
  104. } while ( FALSE );
  105. if ( !error )
  106. rcOs = 0;
  107. return rcOs;
  108. }
  109. WCHAR const * // ret- text for DCT message
  110. TErrorDct::LookupMessage(
  111. UINT msgNumber // in - message number DCT_MSG_???
  112. )
  113. {
  114. WCHAR const * msg = NULL;
  115. return msg;
  116. }
  117. WCHAR * // ret-text for system or EA error
  118. TErrorDct::ErrorCodeToText(
  119. DWORD code ,// in -message code
  120. DWORD lenMsg ,// in -length of message text area
  121. WCHAR * msg // out-returned message text
  122. )
  123. {
  124. if ( SUCCEEDED(code) )
  125. {
  126. return TError::ErrorCodeToText(code,lenMsg,msg);
  127. }
  128. else
  129. {
  130. if ( HRESULT_FACILITY(code) == FACILITY_WIN32 )
  131. {
  132. return TError::ErrorCodeToText(HRESULT_CODE(code),lenMsg,msg);
  133. }
  134. else
  135. {
  136. //Translate ADSI errors to DCT errors so message can be written.
  137. DWORD msgId = 0;
  138. switch ( code )
  139. {
  140. case (E_ADS_BAD_PATHNAME) : msgId = DCT_MSG_E_MSG_ADS_BAD_PATHNAME;
  141. break;
  142. case (E_ADS_INVALID_DOMAIN_OBJECT) : msgId = DCT_MSG_E_ADS_INVALID_DOMAIN_OBJECT;
  143. break;
  144. case (E_ADS_INVALID_USER_OBJECT) : msgId = DCT_MSG_E_ADS_INVALID_USER_OBJECT;
  145. break;
  146. case (E_ADS_INVALID_COMPUTER_OBJECT) : msgId = DCT_MSG_E_ADS_INVALID_COMPUTER_OBJECT;
  147. break;
  148. case (E_ADS_UNKNOWN_OBJECT) : msgId = DCT_MSG_E_ADS_UNKNOWN_OBJECT;
  149. break;
  150. case (E_ADS_PROPERTY_NOT_SET) : msgId = DCT_MSG_E_ADS_PROPERTY_NOT_SET;
  151. break;
  152. case (E_ADS_PROPERTY_NOT_SUPPORTED) : msgId = DCT_MSG_E_ADS_PROPERTY_NOT_SUPPORTED;
  153. break;
  154. case (E_ADS_PROPERTY_INVALID) : msgId = DCT_MSG_E_ADS_PROPERTY_INVALID;
  155. break;
  156. case (E_ADS_BAD_PARAMETER) : msgId = DCT_MSG_E_ADS_BAD_PARAMETER;
  157. break;
  158. case (E_ADS_OBJECT_UNBOUND) : msgId = DCT_MSG_E_ADS_OBJECT_UNBOUND;
  159. break;
  160. case (E_ADS_PROPERTY_NOT_MODIFIED) : msgId = DCT_MSG_E_ADS_PROPERTY_NOT_MODIFIED;
  161. break;
  162. case (E_ADS_PROPERTY_MODIFIED) : msgId = DCT_MSG_E_ADS_PROPERTY_MODIFIED;
  163. break;
  164. case (E_ADS_CANT_CONVERT_DATATYPE) : msgId = DCT_MSG_E_ADS_CANT_CONVERT_DATATYPE;
  165. break;
  166. case (E_ADS_PROPERTY_NOT_FOUND) : msgId = DCT_MSG_E_ADS_PROPERTY_NOT_FOUND;
  167. break;
  168. case (E_ADS_OBJECT_EXISTS) : msgId = DCT_MSG_E_ADS_OBJECT_EXISTS;
  169. break;
  170. case (E_ADS_SCHEMA_VIOLATION) : msgId = DCT_MSG_E_ADS_SCHEMA_VIOLATION;
  171. break;
  172. case (E_ADS_COLUMN_NOT_SET) : msgId = DCT_MSG_E_ADS_COLUMN_NOT_SET;
  173. break;
  174. case (E_ADS_INVALID_FILTER) : msgId = DCT_MSG_E_ADS_INVALID_FILTER;
  175. break;
  176. default : msgId = 0;
  177. }
  178. if ( !msgId )
  179. {
  180. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
  181. | FORMAT_MESSAGE_MAX_WIDTH_MASK
  182. | FORMAT_MESSAGE_IGNORE_INSERTS
  183. | 80,
  184. NULL,
  185. code,
  186. 0,
  187. msg,
  188. lenMsg,
  189. NULL );
  190. }
  191. else
  192. {
  193. static HMODULE hDctMsg = NULL;
  194. DWORD rc = 0;
  195. if ( ! hDctMsg )
  196. {
  197. hDctMsg = LoadLibrary(L"McsDmMsg.DLL");
  198. if ( ! hDctMsg )
  199. {
  200. rc = GetLastError();
  201. }
  202. }
  203. if ( ! rc )
  204. {
  205. FormatMessage(FORMAT_MESSAGE_FROM_HMODULE,
  206. hDctMsg,
  207. msgId,
  208. 0,
  209. msg,
  210. lenMsg,
  211. NULL);
  212. }
  213. else
  214. {
  215. swprintf(msg,L"McsDomMsg.DLL not loaded, rc=%ld, MessageNumber = %lx",rc,msgId);
  216. }
  217. }
  218. }
  219. }
  220. return msg;
  221. }
  222. //-----------------------------------------------------------------------------
  223. // System Error message with format and arguments
  224. //-----------------------------------------------------------------------------
  225. void __cdecl
  226. TErrorDct::SysMsgWrite(
  227. int num ,// in -error number/level code
  228. DWORD lastRc ,// in -error return code
  229. UINT msgNumber ,// in -constant for message
  230. ... // in -printf args to msg pattern
  231. )
  232. {
  233. WCHAR suffix[TERR_MAX_MSG_LEN] = L"";
  234. WCHAR * pMsg = NULL;
  235. va_list argPtr;
  236. int len;
  237. // When an error occurs while in a constructor for a global object,
  238. // the TError object may not yet exist. In this case, "this" is zero
  239. // and we gotta get out of here before we generate a protection exception.
  240. if ( !this )
  241. return;
  242. static HMODULE hDctMsg = NULL;
  243. DWORD rc = 0;
  244. if ( ! hDctMsg )
  245. {
  246. hDctMsg = LoadLibrary(L"McsDmMsg.DLL");
  247. if ( ! hDctMsg )
  248. {
  249. rc = GetLastError();
  250. }
  251. }
  252. va_start(argPtr,msgNumber);
  253. if ( ! rc )
  254. {
  255. len = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE,
  256. hDctMsg,
  257. msgNumber,
  258. 0,
  259. suffix,
  260. DIM(suffix),
  261. &argPtr);
  262. }
  263. else
  264. {
  265. swprintf(suffix,L"McsDomMsg.DLL not loaded, rc=%ld, MessageNumber = %lx",rc,msgNumber);
  266. }
  267. va_end(argPtr);
  268. // Change any imbedded CR or LF to blank.
  269. for ( pMsg = suffix;
  270. *pMsg;
  271. pMsg++ )
  272. {
  273. if ( (*pMsg == L'\x0D') || (*pMsg == L'\x0A') )
  274. *pMsg = L' ';
  275. }
  276. // append the system message for the lastRc at the end.
  277. len = UStrLen(suffix);
  278. if ( len < DIM(suffix) - 1 )
  279. {
  280. ErrorCodeToText(lastRc, DIM(suffix) - len - 1, suffix + len );
  281. }
  282. suffix[DIM(suffix) - 1] = '\0';
  283. va_end(argPtr);
  284. MsgProcess(num, suffix);
  285. }
  286. //-----------------------------------------------------------------------------
  287. // System Error message with format and arguments
  288. //-----------------------------------------------------------------------------
  289. void __cdecl
  290. TErrorDct::MsgWrite(
  291. int num ,// in -error number/level code
  292. UINT msgNumber ,// in -constant for message
  293. ... // in -printf args to msg pattern
  294. )
  295. {
  296. // When an error occurs while in a constructor for a global object,
  297. // the TError object may not yet exist. In this case, "this" is zero
  298. // and we gotta get out of here before we generate a protection exception.
  299. if ( !this )
  300. return;
  301. static HMODULE hDctMsg = NULL;
  302. DWORD rc = 0;
  303. if ( ! hDctMsg )
  304. {
  305. hDctMsg = LoadLibrary(L"McsDmMsg.DLL");
  306. if ( ! hDctMsg )
  307. {
  308. DWORD rc = GetLastError();
  309. }
  310. }
  311. WCHAR suffix[TERR_MAX_MSG_LEN] = L"";
  312. va_list argPtr;
  313. va_start(argPtr,msgNumber);
  314. if ( rc == 0 )
  315. {
  316. FormatMessage(FORMAT_MESSAGE_FROM_HMODULE,
  317. hDctMsg,
  318. msgNumber,
  319. 0,
  320. suffix,
  321. DIM(suffix),
  322. &argPtr);
  323. }
  324. else
  325. {
  326. swprintf(suffix,L"McsDomMsg.DLL not loaded, rc=%ld, MessageNumber = %lx",rc,msgNumber);
  327. }
  328. if ( suffix[UStrLen(suffix)-1] == L'\n' )
  329. {
  330. suffix[UStrLen(suffix)-1] = L'\0';
  331. }
  332. va_end(argPtr);
  333. MsgProcess(num, suffix);
  334. }
  335. void __cdecl
  336. TErrorDct::DbgMsgWrite(
  337. int num ,// in -error number/level code
  338. WCHAR const msg[] ,// in -error message to display
  339. ... // in -printf args to msg pattern
  340. )
  341. {
  342. // When an error occurs while in a constructor for a global object,
  343. // the TError object may not yet exist. In this case, "this" is zero
  344. // and we gotta get out of here before we generate a protection exception.
  345. if ( !this )
  346. return;
  347. WCHAR suffix[TERR_MAX_MSG_LEN];
  348. va_list argPtr;
  349. va_start(argPtr,msg);
  350. _vsnwprintf(suffix, DIM(suffix) - 1, msg, argPtr);
  351. suffix[DIM(suffix) - 1] = L'\0';
  352. va_end(argPtr);
  353. MsgProcess(num, suffix);
  354. }