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.

535 lines
15 KiB

  1. #include <precomp.h>
  2. #include "wzcsvc.h"
  3. #include "intflist.h"
  4. #include "tracing.h"
  5. // internal-use tracing variables
  6. UINT g_nLineNo;
  7. LPSTR g_szFileName;
  8. // handles for database usage
  9. extern JET_SESID serverSession;
  10. extern JET_DBID databasehandle;
  11. extern JET_TABLEID tablehandle;
  12. extern SESSION_CONTAINER sesscon;
  13. //logging database states
  14. // global buffers to be used when formatting database
  15. // logging message parameters
  16. WCHAR g_wszDbLogBuffer[DBLOG_SZFMT_BUFFS][DBLOG_SZFMT_SIZE];
  17. // global tracing variables
  18. DWORD g_TraceLog;
  19. // debug utility calls
  20. VOID _DebugPrint(DWORD dwFlags, LPCSTR lpFormat, ...)
  21. {
  22. va_list arglist;
  23. va_start(arglist, lpFormat);
  24. TraceVprintfExA(
  25. g_TraceLog,
  26. dwFlags | TRACE_USE_MASK,
  27. lpFormat,
  28. arglist);
  29. }
  30. // if bCheck is not true, print out the assert message & user defined string.
  31. VOID _DebugAssert(BOOL bChecked, LPCSTR lpFormat, ...)
  32. {
  33. if (!bChecked)
  34. {
  35. va_list arglist;
  36. CHAR pBuffer[500];
  37. LPSTR pFileName;
  38. pFileName = strrchr(g_szFileName, '\\');
  39. if (pFileName == NULL)
  40. pFileName = g_szFileName;
  41. else
  42. pFileName++;
  43. sprintf(pBuffer,"##Assert %s:%d## ", pFileName, g_nLineNo);
  44. strcat(pBuffer, lpFormat);
  45. va_start(arglist, lpFormat);
  46. TraceVprintfExA(
  47. g_TraceLog,
  48. TRC_ASSERT | TRACE_USE_MASK,
  49. pBuffer,
  50. arglist);
  51. }
  52. }
  53. VOID _DebugBinary(DWORD dwFlags, LPCSTR lpMessage, LPBYTE pBuffer, UINT nBuffLen)
  54. {
  55. CHAR strHex[128];
  56. UINT nMsgLen = strlen(lpMessage);
  57. if (3*nBuffLen >= 120)
  58. {
  59. strcpy(strHex, "##Binary data too large##");
  60. }
  61. else
  62. {
  63. LPSTR pHexDigit = strHex;
  64. UINT i = nBuffLen;
  65. while(i > 0)
  66. {
  67. sprintf(pHexDigit, "%02x ", *pBuffer);
  68. pHexDigit += 3;
  69. pBuffer++;
  70. i--;
  71. }
  72. *pHexDigit = '\0';
  73. }
  74. TracePrintfExA(
  75. g_TraceLog,
  76. dwFlags | TRACE_USE_MASK,
  77. "%s [%d]:{%s}", lpMessage, nBuffLen, strHex);
  78. }
  79. VOID TrcInitialize()
  80. {
  81. #ifdef DBG
  82. g_TraceLog = TraceRegister(TRC_NAME);
  83. #endif
  84. }
  85. VOID TrcTerminate()
  86. {
  87. #ifdef DBG
  88. TraceDeregister(g_TraceLog);
  89. #endif
  90. }
  91. //------------- Database Logging functions -------------------
  92. DWORD _DBRecord (
  93. DWORD eventID,
  94. PWZC_DB_RECORD pDbRecord,
  95. va_list *pvaList)
  96. {
  97. DWORD dwErr = ERROR_SUCCESS;
  98. WCHAR wchBuffer[MAX_RAW_DATA_SIZE/sizeof(WCHAR)];
  99. HINSTANCE hInstance = WZCGetSPResModule();
  100. if (hInstance == NULL)
  101. dwErr = ERROR_DLL_INIT_FAILED;
  102. if (dwErr == ERROR_SUCCESS)
  103. {
  104. // format the message
  105. if (FormatMessageW(
  106. FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_MAX_WIDTH_MASK,
  107. hInstance,
  108. eventID,
  109. 0, // Default language
  110. wchBuffer,
  111. sizeof(wchBuffer)/sizeof(WCHAR),
  112. pvaList) == 0)
  113. {
  114. dwErr = GetLastError();
  115. }
  116. }
  117. if (dwErr == ERROR_SUCCESS)
  118. {
  119. pDbRecord->message.pData = (LPBYTE)wchBuffer;
  120. pDbRecord->message.dwDataLen = sizeof(WCHAR)*(wcslen(wchBuffer) + 1);
  121. //make a insertion
  122. dwErr = AddWZCDbLogRecord(NULL, 0, pDbRecord, NULL);
  123. }
  124. return dwErr;
  125. }
  126. DWORD DbLogWzcError (
  127. DWORD eventID,
  128. PINTF_CONTEXT pIntfContext,
  129. ...
  130. )
  131. {
  132. DWORD dwErr = ERROR_SUCCESS;
  133. va_list argList;
  134. WZC_DB_RECORD DbRecord = {0};
  135. BOOL bLogEnabled;
  136. if (!g_wzcInternalCtxt.bValid)
  137. {
  138. dwErr = ERROR_ARENA_TRASHED;
  139. goto exit;
  140. }
  141. va_start(argList, pIntfContext);
  142. EnterCriticalSection(&g_wzcInternalCtxt.csContext);
  143. bLogEnabled = ((g_wzcInternalCtxt.wzcContext.dwFlags & WZC_CTXT_LOGGING_ON) != 0);
  144. LeaveCriticalSection(&g_wzcInternalCtxt.csContext);
  145. // If the database is not opened or the logging functionality is disabled,
  146. // do not record any thing
  147. if (!bLogEnabled || !IsDBOpened())
  148. goto exit;
  149. // prepare the info that is about to be logged.
  150. // get the service specific info first (i.e WZC specific part)
  151. // then build up the message.
  152. DbLogInitDbRecord(DBLOG_CATEG_ERR, pIntfContext, &DbRecord);
  153. dwErr = _DBRecord(
  154. eventID,
  155. &DbRecord,
  156. &argList);
  157. exit:
  158. return dwErr;
  159. }
  160. DWORD DbLogWzcInfo (
  161. DWORD eventID,
  162. PINTF_CONTEXT pIntfContext,
  163. ...
  164. )
  165. {
  166. DWORD dwErr = ERROR_SUCCESS;
  167. va_list argList;
  168. WZC_DB_RECORD DbRecord = {0};
  169. BOOL bLogEnabled;
  170. LPWSTR wszContext = NULL;
  171. DWORD nchContext = 0;
  172. if (!g_wzcInternalCtxt.bValid)
  173. {
  174. dwErr = ERROR_ARENA_TRASHED;
  175. goto exit;
  176. }
  177. va_start(argList, pIntfContext);
  178. EnterCriticalSection(&g_wzcInternalCtxt.csContext);
  179. bLogEnabled = ((g_wzcInternalCtxt.wzcContext.dwFlags & WZC_CTXT_LOGGING_ON) != 0);
  180. LeaveCriticalSection(&g_wzcInternalCtxt.csContext);
  181. // If the database is not opened or the logging functionality is disabled,
  182. // do not record any thing
  183. if (!bLogEnabled || !IsDBOpened())
  184. goto exit;
  185. // prepare the info that is about to be logged.
  186. // get the service specific info first (i.e WZC specific part)
  187. // then build up the message.
  188. DbLogInitDbRecord(DBLOG_CATEG_INFO, pIntfContext, &DbRecord);
  189. // if WZCSVC_USR_CFGCHANGE, build the context string
  190. if (eventID == WZCSVC_USR_CFGCHANGE &&
  191. pIntfContext != NULL)
  192. {
  193. DWORD nOffset = 0;
  194. DWORD nchWritten = 0;
  195. nchContext = 64; // large enough for "Flags = 0x00000000"
  196. if (pIntfContext->pwzcPList != NULL)
  197. {
  198. // large enough for "{SSID, Infrastructure, Flags}"
  199. nchContext += pIntfContext->pwzcPList->NumberOfItems * 128;
  200. }
  201. wszContext = (LPWSTR)MemCAlloc(nchContext * sizeof(WCHAR));
  202. if (wszContext == NULL)
  203. dwErr = GetLastError();
  204. if (dwErr == ERROR_SUCCESS)
  205. {
  206. nchWritten = nchContext;
  207. dwErr = DbLogFmtFlags(
  208. wszContext,
  209. &nchWritten,
  210. pIntfContext->dwCtlFlags);
  211. if (dwErr == ERROR_SUCCESS)
  212. nOffset += nchWritten;
  213. }
  214. if (dwErr == ERROR_SUCCESS && pIntfContext->pwzcPList != NULL)
  215. {
  216. UINT i;
  217. for (i = 0; i < pIntfContext->pwzcPList->NumberOfItems; i++)
  218. {
  219. nchWritten = nchContext - nOffset;
  220. dwErr = DbLogFmtWConfig(
  221. wszContext + nOffset,
  222. &nchWritten,
  223. &(pIntfContext->pwzcPList->Config[i]));
  224. if (dwErr != ERROR_SUCCESS)
  225. break;
  226. nOffset += nchWritten;
  227. }
  228. }
  229. if (dwErr == ERROR_SUCCESS)
  230. {
  231. DbRecord.context.pData = (LPBYTE)wszContext;
  232. DbRecord.context.dwDataLen = (wcslen(wszContext) + 1) * sizeof(WCHAR);
  233. }
  234. }
  235. else if (eventID == WZCSVC_BLIST_CHANGED &&
  236. pIntfContext != NULL &&
  237. pIntfContext->pwzcBList != NULL &&
  238. pIntfContext->pwzcBList->NumberOfItems != 0)
  239. {
  240. DWORD nOffset = 0;
  241. DWORD nchWritten = 0;
  242. nchContext = pIntfContext->pwzcBList->NumberOfItems * 128;
  243. wszContext = (LPWSTR)MemCAlloc(nchContext * sizeof(WCHAR));
  244. if (wszContext == NULL)
  245. dwErr = GetLastError();
  246. if (dwErr == ERROR_SUCCESS)
  247. {
  248. UINT i;
  249. for (i = 0; i < pIntfContext->pwzcBList->NumberOfItems; i++)
  250. {
  251. nchWritten = nchContext - nOffset;
  252. dwErr = DbLogFmtWConfig(
  253. wszContext + nOffset,
  254. &nchWritten,
  255. &(pIntfContext->pwzcBList->Config[i]));
  256. if (dwErr != ERROR_SUCCESS)
  257. break;
  258. nOffset += nchWritten;
  259. }
  260. }
  261. if (dwErr == ERROR_SUCCESS)
  262. {
  263. DbRecord.context.pData = (LPBYTE)wszContext;
  264. DbRecord.context.dwDataLen = (wcslen(wszContext) + 1) * sizeof(WCHAR);
  265. }
  266. }
  267. dwErr = _DBRecord(
  268. eventID,
  269. &DbRecord,
  270. &argList);
  271. exit:
  272. MemFree(wszContext);
  273. return dwErr;
  274. }
  275. // Initializes the WZC_DB_RECORD
  276. DWORD DbLogInitDbRecord(
  277. DWORD dwCategory,
  278. PINTF_CONTEXT pIntfContext,
  279. PWZC_DB_RECORD pDbRecord)
  280. {
  281. DWORD dwErr = ERROR_SUCCESS;
  282. if (pDbRecord == NULL)
  283. {
  284. dwErr = ERROR_INVALID_PARAMETER;
  285. }
  286. else
  287. {
  288. ZeroMemory(pDbRecord, sizeof(WZC_DB_RECORD));
  289. pDbRecord->componentid = DBLOG_COMPID_WZCSVC;
  290. pDbRecord->category = dwCategory;
  291. if (pIntfContext != NULL)
  292. {
  293. pDbRecord->ssid.pData = (LPBYTE)DbLogFmtSSID(5,&(pIntfContext->wzcCurrent.Ssid));
  294. pDbRecord->ssid.dwDataLen = sizeof(WCHAR)*(wcslen((LPWSTR)pDbRecord->ssid.pData) + 1);
  295. pDbRecord->localmac.pData = (LPBYTE)DbLogFmtBSSID(6, pIntfContext->ndLocalMac);
  296. pDbRecord->localmac.dwDataLen = sizeof(WCHAR)*(wcslen((LPWSTR)pDbRecord->localmac.pData) + 1);
  297. pDbRecord->remotemac.pData = (LPBYTE)DbLogFmtBSSID(7, pIntfContext->wzcCurrent.MacAddress);
  298. pDbRecord->remotemac.dwDataLen = sizeof(WCHAR)*(wcslen((LPWSTR)pDbRecord->remotemac.pData) + 1);
  299. }
  300. }
  301. return dwErr;
  302. }
  303. // Formats an SSID in the given formatting buffer
  304. LPWSTR DbLogFmtSSID(
  305. UINT nBuff, // index of the format buffer to use (0 .. DBLOG_SZFMT_BUFFS)
  306. PNDIS_802_11_SSID pndSSid)
  307. {
  308. UINT nFmtLen;
  309. DbgAssert((nBuff < DBLOG_SZFMT_SIZE, "Illegal buffer index in DbLogFmtSSID"));
  310. nFmtLen = MultiByteToWideChar(
  311. CP_ACP,
  312. 0,
  313. pndSSid->Ssid,
  314. min (pndSSid->SsidLength, DBLOG_SZFMT_SIZE-1),
  315. g_wszDbLogBuffer[nBuff],
  316. DBLOG_SZFMT_SIZE-1);
  317. if (nFmtLen == DBLOG_SZFMT_SIZE-1)
  318. wcscpy(&(g_wszDbLogBuffer[nBuff][DBLOG_SZFMT_SIZE-3]), L"..");
  319. else
  320. g_wszDbLogBuffer[nBuff][nFmtLen] = '\0';
  321. return g_wszDbLogBuffer[nBuff];
  322. }
  323. // Formats a BSSID (MAC address) in the given formatting buffer
  324. LPWSTR DbLogFmtBSSID(
  325. UINT nBuff,
  326. NDIS_802_11_MAC_ADDRESS ndBSSID)
  327. {
  328. UINT i, j;
  329. BOOL bAllZero = TRUE;
  330. DbgAssert((nBuff < DBLOG_SZFMT_SIZE, "Illegal buffer index in DbLogFmtSSID"));
  331. g_wszDbLogBuffer[nBuff][0] = L'\0';
  332. for (j = 0, i = 0; i < sizeof(NDIS_802_11_MAC_ADDRESS); i++)
  333. {
  334. BYTE nHex;
  335. if (ndBSSID[i] != 0)
  336. bAllZero = FALSE;
  337. nHex = (ndBSSID[i] & 0xf0) >> 4;
  338. g_wszDbLogBuffer[nBuff][j++] = HEX2WCHAR(nHex);
  339. nHex = (ndBSSID[i] & 0x0f);
  340. g_wszDbLogBuffer[nBuff][j++] = HEX2WCHAR(nHex);
  341. g_wszDbLogBuffer[nBuff][j++] = MAC_SEPARATOR;
  342. }
  343. if (bAllZero)
  344. g_wszDbLogBuffer[nBuff][0] = L'\0';
  345. else if (j > 0)
  346. g_wszDbLogBuffer[nBuff][j-1] = L'\0';
  347. return g_wszDbLogBuffer[nBuff];
  348. }
  349. // Formats the INTF_CONTEXT::dwCtlFlags field for logging
  350. DWORD DbLogFmtFlags(
  351. LPWSTR wszBuffer, // buffer to place the result into
  352. LPDWORD pnchBuffer, // in: num of chars in the buffer; out: number of chars written to the buffer
  353. DWORD dwFlags) // interface flags to log
  354. {
  355. DWORD dwErr = ERROR_SUCCESS;
  356. UINT nchBuffer;
  357. LPVOID pvArgs[5];
  358. WCHAR wszArgs[5][33];
  359. HINSTANCE hInstance = WZCGetSPResModule();
  360. if (pnchBuffer == NULL || *pnchBuffer == 0)
  361. {
  362. dwErr = ERROR_INVALID_PARAMETER;
  363. goto exit;
  364. }
  365. nchBuffer = (*pnchBuffer);
  366. *pnchBuffer = 0;
  367. if (hInstance == NULL)
  368. {
  369. dwErr = ERROR_DLL_INIT_FAILED;
  370. goto exit;
  371. }
  372. pvArgs[0] = _itow((dwFlags & INTFCTL_ENABLED) != 0, wszArgs[0], 10);
  373. pvArgs[1] = _itow((dwFlags & INTFCTL_FALLBACK) != 0, wszArgs[1], 10);
  374. pvArgs[2] = _itow((dwFlags & INTFCTL_CM_MASK), wszArgs[2], 10);
  375. pvArgs[3] = _itow((dwFlags & INTFCTL_VOLATILE) != 0, wszArgs[3], 10);
  376. pvArgs[4] = _itow((dwFlags & INTFCTL_POLICY) != 0, wszArgs[4], 10);
  377. // format the message
  378. *pnchBuffer = FormatMessageW(
  379. FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  380. hInstance,
  381. WZCSVC_DETAILS_FLAGS,
  382. 0, // Default language
  383. wszBuffer,
  384. nchBuffer,
  385. (va_list*)pvArgs);
  386. if (*pnchBuffer == 0)
  387. dwErr = GetLastError();
  388. exit:
  389. return dwErr;
  390. }
  391. // Formats a WZC_WLAN_CONFIG structure for logging
  392. DWORD DbLogFmtWConfig(
  393. LPWSTR wszBuffer, // buffer to place the result into
  394. LPDWORD pnchBuffer, // in: num of chars in the buffer; out: number of chars written to the buffer
  395. PWZC_WLAN_CONFIG pWzcCfg) // WZC_WLAN_CONFIG object to log
  396. {
  397. DWORD dwErr = ERROR_SUCCESS;
  398. UINT nchBuffer;
  399. LPVOID pvArgs[5];
  400. WCHAR wszArgs[4][33];
  401. HINSTANCE hInstance = WZCGetSPResModule();
  402. if (pnchBuffer == NULL || *pnchBuffer == 0)
  403. {
  404. dwErr = ERROR_INVALID_PARAMETER;
  405. goto exit;
  406. }
  407. nchBuffer = (*pnchBuffer);
  408. *pnchBuffer = 0;
  409. if (hInstance == NULL)
  410. {
  411. dwErr = ERROR_DLL_INIT_FAILED;
  412. goto exit;
  413. }
  414. pvArgs[0] = (LPVOID)DbLogFmtSSID(8, &(pWzcCfg->Ssid));
  415. pvArgs[1] = _itow(pWzcCfg->InfrastructureMode, wszArgs[0], 10);
  416. pvArgs[2] = _itow(pWzcCfg->Privacy, wszArgs[1], 10);
  417. pvArgs[3] = _itow((pWzcCfg->dwCtlFlags & WZCCTL_VOLATILE) != 0, wszArgs[2], 10);
  418. pvArgs[4] = _itow((pWzcCfg->dwCtlFlags & WZCCTL_POLICY) != 0, wszArgs[3], 10);
  419. // format the message
  420. *pnchBuffer = FormatMessageW(
  421. FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  422. hInstance,
  423. WZCSVC_DETAILS_WCONFIG,
  424. 0, // Default language
  425. wszBuffer,
  426. nchBuffer,
  427. (va_list*)pvArgs);
  428. if (*pnchBuffer == 0)
  429. dwErr = GetLastError();
  430. exit:
  431. return dwErr;
  432. }
  433. //---------------------------------------
  434. // GetSPResModule: Utility function used to return
  435. // the handle to the module having WZC UI resources
  436. // (needed for XP.QFE & XP.SP1 builds)
  437. HINSTANCE
  438. WZCGetSPResModule()
  439. {
  440. static HINSTANCE st_hModule = NULL;
  441. if (st_hModule == NULL)
  442. {
  443. WCHAR wszFullPath[_MAX_PATH];
  444. if (ExpandEnvironmentStrings(
  445. L"%systemroot%\\system32\\xpsp1res.dll",
  446. wszFullPath,
  447. _MAX_PATH) != 0)
  448. {
  449. st_hModule = LoadLibraryEx(
  450. wszFullPath,
  451. NULL,
  452. 0);
  453. }
  454. }
  455. return st_hModule;
  456. }