#include #include "wzcsvc.h" #include "intflist.h" #include "tracing.h" // internal-use tracing variables UINT g_nLineNo; LPSTR g_szFileName; // handles for database usage extern JET_SESID serverSession; extern JET_DBID databasehandle; extern JET_TABLEID tablehandle; extern SESSION_CONTAINER sesscon; //logging database states // global buffers to be used when formatting database // logging message parameters WCHAR g_wszDbLogBuffer[DBLOG_SZFMT_BUFFS][DBLOG_SZFMT_SIZE]; // global tracing variables DWORD g_TraceLog; // debug utility calls VOID _DebugPrint(DWORD dwFlags, LPCSTR lpFormat, ...) { va_list arglist; va_start(arglist, lpFormat); TraceVprintfExA( g_TraceLog, dwFlags | TRACE_USE_MASK, lpFormat, arglist); } // if bCheck is not true, print out the assert message & user defined string. VOID _DebugAssert(BOOL bChecked, LPCSTR lpFormat, ...) { if (!bChecked) { va_list arglist; CHAR pBuffer[500]; LPSTR pFileName; pFileName = strrchr(g_szFileName, '\\'); if (pFileName == NULL) pFileName = g_szFileName; else pFileName++; sprintf(pBuffer,"##Assert %s:%d## ", pFileName, g_nLineNo); strcat(pBuffer, lpFormat); va_start(arglist, lpFormat); TraceVprintfExA( g_TraceLog, TRC_ASSERT | TRACE_USE_MASK, pBuffer, arglist); } } VOID _DebugBinary(DWORD dwFlags, LPCSTR lpMessage, LPBYTE pBuffer, UINT nBuffLen) { CHAR strHex[128]; UINT nMsgLen = strlen(lpMessage); if (3*nBuffLen >= 120) { strcpy(strHex, "##Binary data too large##"); } else { LPSTR pHexDigit = strHex; UINT i = nBuffLen; while(i > 0) { sprintf(pHexDigit, "%02x ", *pBuffer); pHexDigit += 3; pBuffer++; i--; } *pHexDigit = '\0'; } TracePrintfExA( g_TraceLog, dwFlags | TRACE_USE_MASK, "%s [%d]:{%s}", lpMessage, nBuffLen, strHex); } VOID TrcInitialize() { #ifdef DBG g_TraceLog = TraceRegister(TRC_NAME); #endif } VOID TrcTerminate() { #ifdef DBG TraceDeregister(g_TraceLog); #endif } //------------- Database Logging functions ------------------- DWORD _DBRecord ( DWORD eventID, PWZC_DB_RECORD pDbRecord, va_list *pvaList) { DWORD dwErr = ERROR_SUCCESS; WCHAR wchBuffer[MAX_RAW_DATA_SIZE/sizeof(WCHAR)]; HINSTANCE hInstance = WZCGetSPResModule(); if (hInstance == NULL) dwErr = ERROR_DLL_INIT_FAILED; if (dwErr == ERROR_SUCCESS) { // format the message if (FormatMessageW( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_MAX_WIDTH_MASK, hInstance, eventID, 0, // Default language wchBuffer, sizeof(wchBuffer)/sizeof(WCHAR), pvaList) == 0) { dwErr = GetLastError(); } } if (dwErr == ERROR_SUCCESS) { pDbRecord->message.pData = (LPBYTE)wchBuffer; pDbRecord->message.dwDataLen = sizeof(WCHAR)*(wcslen(wchBuffer) + 1); //make a insertion dwErr = AddWZCDbLogRecord(NULL, 0, pDbRecord, NULL); } return dwErr; } DWORD DbLogWzcError ( DWORD eventID, PINTF_CONTEXT pIntfContext, ... ) { DWORD dwErr = ERROR_SUCCESS; va_list argList; WZC_DB_RECORD DbRecord = {0}; BOOL bLogEnabled; if (!g_wzcInternalCtxt.bValid) { dwErr = ERROR_ARENA_TRASHED; goto exit; } va_start(argList, pIntfContext); EnterCriticalSection(&g_wzcInternalCtxt.csContext); bLogEnabled = ((g_wzcInternalCtxt.wzcContext.dwFlags & WZC_CTXT_LOGGING_ON) != 0); LeaveCriticalSection(&g_wzcInternalCtxt.csContext); // If the database is not opened or the logging functionality is disabled, // do not record any thing if (!bLogEnabled || !IsDBOpened()) goto exit; // prepare the info that is about to be logged. // get the service specific info first (i.e WZC specific part) // then build up the message. DbLogInitDbRecord(DBLOG_CATEG_ERR, pIntfContext, &DbRecord); dwErr = _DBRecord( eventID, &DbRecord, &argList); exit: return dwErr; } DWORD DbLogWzcInfo ( DWORD eventID, PINTF_CONTEXT pIntfContext, ... ) { DWORD dwErr = ERROR_SUCCESS; va_list argList; WZC_DB_RECORD DbRecord = {0}; BOOL bLogEnabled; LPWSTR wszContext = NULL; DWORD nchContext = 0; if (!g_wzcInternalCtxt.bValid) { dwErr = ERROR_ARENA_TRASHED; goto exit; } va_start(argList, pIntfContext); EnterCriticalSection(&g_wzcInternalCtxt.csContext); bLogEnabled = ((g_wzcInternalCtxt.wzcContext.dwFlags & WZC_CTXT_LOGGING_ON) != 0); LeaveCriticalSection(&g_wzcInternalCtxt.csContext); // If the database is not opened or the logging functionality is disabled, // do not record any thing if (!bLogEnabled || !IsDBOpened()) goto exit; // prepare the info that is about to be logged. // get the service specific info first (i.e WZC specific part) // then build up the message. DbLogInitDbRecord(DBLOG_CATEG_INFO, pIntfContext, &DbRecord); // if WZCSVC_USR_CFGCHANGE, build the context string if (eventID == WZCSVC_USR_CFGCHANGE && pIntfContext != NULL) { DWORD nOffset = 0; DWORD nchWritten = 0; nchContext = 64; // large enough for "Flags = 0x00000000" if (pIntfContext->pwzcPList != NULL) { // large enough for "{SSID, Infrastructure, Flags}" nchContext += pIntfContext->pwzcPList->NumberOfItems * 128; } wszContext = (LPWSTR)MemCAlloc(nchContext * sizeof(WCHAR)); if (wszContext == NULL) dwErr = GetLastError(); if (dwErr == ERROR_SUCCESS) { nchWritten = nchContext; dwErr = DbLogFmtFlags( wszContext, &nchWritten, pIntfContext->dwCtlFlags); if (dwErr == ERROR_SUCCESS) nOffset += nchWritten; } if (dwErr == ERROR_SUCCESS && pIntfContext->pwzcPList != NULL) { UINT i; for (i = 0; i < pIntfContext->pwzcPList->NumberOfItems; i++) { nchWritten = nchContext - nOffset; dwErr = DbLogFmtWConfig( wszContext + nOffset, &nchWritten, &(pIntfContext->pwzcPList->Config[i])); if (dwErr != ERROR_SUCCESS) break; nOffset += nchWritten; } } if (dwErr == ERROR_SUCCESS) { DbRecord.context.pData = (LPBYTE)wszContext; DbRecord.context.dwDataLen = (wcslen(wszContext) + 1) * sizeof(WCHAR); } } else if (eventID == WZCSVC_BLIST_CHANGED && pIntfContext != NULL && pIntfContext->pwzcBList != NULL && pIntfContext->pwzcBList->NumberOfItems != 0) { DWORD nOffset = 0; DWORD nchWritten = 0; nchContext = pIntfContext->pwzcBList->NumberOfItems * 128; wszContext = (LPWSTR)MemCAlloc(nchContext * sizeof(WCHAR)); if (wszContext == NULL) dwErr = GetLastError(); if (dwErr == ERROR_SUCCESS) { UINT i; for (i = 0; i < pIntfContext->pwzcBList->NumberOfItems; i++) { nchWritten = nchContext - nOffset; dwErr = DbLogFmtWConfig( wszContext + nOffset, &nchWritten, &(pIntfContext->pwzcBList->Config[i])); if (dwErr != ERROR_SUCCESS) break; nOffset += nchWritten; } } if (dwErr == ERROR_SUCCESS) { DbRecord.context.pData = (LPBYTE)wszContext; DbRecord.context.dwDataLen = (wcslen(wszContext) + 1) * sizeof(WCHAR); } } dwErr = _DBRecord( eventID, &DbRecord, &argList); exit: MemFree(wszContext); return dwErr; } // Initializes the WZC_DB_RECORD DWORD DbLogInitDbRecord( DWORD dwCategory, PINTF_CONTEXT pIntfContext, PWZC_DB_RECORD pDbRecord) { DWORD dwErr = ERROR_SUCCESS; if (pDbRecord == NULL) { dwErr = ERROR_INVALID_PARAMETER; } else { ZeroMemory(pDbRecord, sizeof(WZC_DB_RECORD)); pDbRecord->componentid = DBLOG_COMPID_WZCSVC; pDbRecord->category = dwCategory; if (pIntfContext != NULL) { pDbRecord->ssid.pData = (LPBYTE)DbLogFmtSSID(5,&(pIntfContext->wzcCurrent.Ssid)); pDbRecord->ssid.dwDataLen = sizeof(WCHAR)*(wcslen((LPWSTR)pDbRecord->ssid.pData) + 1); pDbRecord->localmac.pData = (LPBYTE)DbLogFmtBSSID(6, pIntfContext->ndLocalMac); pDbRecord->localmac.dwDataLen = sizeof(WCHAR)*(wcslen((LPWSTR)pDbRecord->localmac.pData) + 1); pDbRecord->remotemac.pData = (LPBYTE)DbLogFmtBSSID(7, pIntfContext->wzcCurrent.MacAddress); pDbRecord->remotemac.dwDataLen = sizeof(WCHAR)*(wcslen((LPWSTR)pDbRecord->remotemac.pData) + 1); } } return dwErr; } // Formats an SSID in the given formatting buffer LPWSTR DbLogFmtSSID( UINT nBuff, // index of the format buffer to use (0 .. DBLOG_SZFMT_BUFFS) PNDIS_802_11_SSID pndSSid) { UINT nFmtLen; DbgAssert((nBuff < DBLOG_SZFMT_SIZE, "Illegal buffer index in DbLogFmtSSID")); nFmtLen = MultiByteToWideChar( CP_ACP, 0, pndSSid->Ssid, min (pndSSid->SsidLength, DBLOG_SZFMT_SIZE-1), g_wszDbLogBuffer[nBuff], DBLOG_SZFMT_SIZE-1); if (nFmtLen == DBLOG_SZFMT_SIZE-1) wcscpy(&(g_wszDbLogBuffer[nBuff][DBLOG_SZFMT_SIZE-3]), L".."); else g_wszDbLogBuffer[nBuff][nFmtLen] = '\0'; return g_wszDbLogBuffer[nBuff]; } // Formats a BSSID (MAC address) in the given formatting buffer LPWSTR DbLogFmtBSSID( UINT nBuff, NDIS_802_11_MAC_ADDRESS ndBSSID) { UINT i, j; BOOL bAllZero = TRUE; DbgAssert((nBuff < DBLOG_SZFMT_SIZE, "Illegal buffer index in DbLogFmtSSID")); g_wszDbLogBuffer[nBuff][0] = L'\0'; for (j = 0, i = 0; i < sizeof(NDIS_802_11_MAC_ADDRESS); i++) { BYTE nHex; if (ndBSSID[i] != 0) bAllZero = FALSE; nHex = (ndBSSID[i] & 0xf0) >> 4; g_wszDbLogBuffer[nBuff][j++] = HEX2WCHAR(nHex); nHex = (ndBSSID[i] & 0x0f); g_wszDbLogBuffer[nBuff][j++] = HEX2WCHAR(nHex); g_wszDbLogBuffer[nBuff][j++] = MAC_SEPARATOR; } if (bAllZero) g_wszDbLogBuffer[nBuff][0] = L'\0'; else if (j > 0) g_wszDbLogBuffer[nBuff][j-1] = L'\0'; return g_wszDbLogBuffer[nBuff]; } // Formats the INTF_CONTEXT::dwCtlFlags field for logging DWORD DbLogFmtFlags( LPWSTR wszBuffer, // buffer to place the result into LPDWORD pnchBuffer, // in: num of chars in the buffer; out: number of chars written to the buffer DWORD dwFlags) // interface flags to log { DWORD dwErr = ERROR_SUCCESS; UINT nchBuffer; LPVOID pvArgs[5]; WCHAR wszArgs[5][33]; HINSTANCE hInstance = WZCGetSPResModule(); if (pnchBuffer == NULL || *pnchBuffer == 0) { dwErr = ERROR_INVALID_PARAMETER; goto exit; } nchBuffer = (*pnchBuffer); *pnchBuffer = 0; if (hInstance == NULL) { dwErr = ERROR_DLL_INIT_FAILED; goto exit; } pvArgs[0] = _itow((dwFlags & INTFCTL_ENABLED) != 0, wszArgs[0], 10); pvArgs[1] = _itow((dwFlags & INTFCTL_FALLBACK) != 0, wszArgs[1], 10); pvArgs[2] = _itow((dwFlags & INTFCTL_CM_MASK), wszArgs[2], 10); pvArgs[3] = _itow((dwFlags & INTFCTL_VOLATILE) != 0, wszArgs[3], 10); pvArgs[4] = _itow((dwFlags & INTFCTL_POLICY) != 0, wszArgs[4], 10); // format the message *pnchBuffer = FormatMessageW( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_ARGUMENT_ARRAY, hInstance, WZCSVC_DETAILS_FLAGS, 0, // Default language wszBuffer, nchBuffer, (va_list*)pvArgs); if (*pnchBuffer == 0) dwErr = GetLastError(); exit: return dwErr; } // Formats a WZC_WLAN_CONFIG structure for logging DWORD DbLogFmtWConfig( LPWSTR wszBuffer, // buffer to place the result into LPDWORD pnchBuffer, // in: num of chars in the buffer; out: number of chars written to the buffer PWZC_WLAN_CONFIG pWzcCfg) // WZC_WLAN_CONFIG object to log { DWORD dwErr = ERROR_SUCCESS; UINT nchBuffer; LPVOID pvArgs[5]; WCHAR wszArgs[4][33]; HINSTANCE hInstance = WZCGetSPResModule(); if (pnchBuffer == NULL || *pnchBuffer == 0) { dwErr = ERROR_INVALID_PARAMETER; goto exit; } nchBuffer = (*pnchBuffer); *pnchBuffer = 0; if (hInstance == NULL) { dwErr = ERROR_DLL_INIT_FAILED; goto exit; } pvArgs[0] = (LPVOID)DbLogFmtSSID(8, &(pWzcCfg->Ssid)); pvArgs[1] = _itow(pWzcCfg->InfrastructureMode, wszArgs[0], 10); pvArgs[2] = _itow(pWzcCfg->Privacy, wszArgs[1], 10); pvArgs[3] = _itow((pWzcCfg->dwCtlFlags & WZCCTL_VOLATILE) != 0, wszArgs[2], 10); pvArgs[4] = _itow((pWzcCfg->dwCtlFlags & WZCCTL_POLICY) != 0, wszArgs[3], 10); // format the message *pnchBuffer = FormatMessageW( FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_ARGUMENT_ARRAY, hInstance, WZCSVC_DETAILS_WCONFIG, 0, // Default language wszBuffer, nchBuffer, (va_list*)pvArgs); if (*pnchBuffer == 0) dwErr = GetLastError(); exit: return dwErr; } //--------------------------------------- // GetSPResModule: Utility function used to return // the handle to the module having WZC UI resources // (needed for XP.QFE & XP.SP1 builds) HINSTANCE WZCGetSPResModule() { static HINSTANCE st_hModule = NULL; if (st_hModule == NULL) { WCHAR wszFullPath[_MAX_PATH]; if (ExpandEnvironmentStrings( L"%systemroot%\\system32\\xpsp1res.dll", wszFullPath, _MAX_PATH) != 0) { st_hModule = LoadLibraryEx( wszFullPath, NULL, 0); } } return st_hModule; }