// spbranch.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "spbranch.h" #define EXCEPTION_INSUFFICE_RESOURCE ((DWORD )0x00000001L) #define INSERT_CONTEXT CHAR g_szDevName[MAX_PATH] = {0}; //HANDLE g_hHeap; BYTE* g_pbtRequest; BYTE* g_pbtReply; DWORD g_dwEceptionCode; CSpBranch gSpBranch; PTOP_LEVEL_EXCEPTION_FILTER pfnUnhandledExceptionFilterPrev; DWORD GetAnswerToRequest(LPBYTE, DWORD, LPBYTE); DWORD SetExceptionCodeToReply(LPBYTE); void CustomExitProcess(UINT uExitCode); void CleanupProcess(); ErrorCodeEnum GetAdapterLastErr(LPCTSTR, ErrorCodeEnum); LONG WINAPI CustomUnhandleExceptionFilter(PEXCEPTION_POINTERS); void ShowProcessIntegrityLevel(int*); int GetCurrentRunPath(char *pPath); int GetCurrentRVCPath(char *pPath); // ErrorMessage support function. // Retrieves the system error message for the GetLastError() code. // Note: caller must use LocalFree() on the returned LPCTSTR buffer. LPCTSTR ErrorMessage(DWORD error) { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); return((LPCTSTR)lpMsgBuf); } LPCTSTR CmdTypeToString(CMDType type) { switch(type) { case BRCMD_START: return "BRCMD_START"; break; case BRCMD_GETSTATE: return "BRCMD_GETSTATE"; break; case BRCMD_OPENDEV: return "BRCMD_OPENDEV"; break; case BRCMD_CLOSEDEV: return "BRCMD_CLOSEDEV"; break; case BRCMD_GETERROR: return "BRCMD_GETERROR"; break; case BRCMD_SENDCMD: return "BRCMD_SENDCMD"; break; case BRCMD_GETDEVINFO: return "BRCMD_GETDEVINFO"; break; case BRCMD_END: default: return "BRCMD_END"; break; } return "BRCMD_END"; } LPCTSTR DevStateToString(DevThreadState state) { switch(state) { case State_NoInit: return "State_NoInit"; break; case State_Invalid: return "State_Invalid"; break; case State_LoadFailed: return "State_LoadFailed"; break; case State_LoadSucc: return "State_LoadSucc"; break; case State_OpenFailed: return "State_OpenFailed"; break; case State_Opened: return "State_Opened"; break; case State_Idle: return "State_Idle"; break; case State_Busy: return "State_Busy"; break; case State_Max: default: return "State_Max"; break; } return "State_Max"; } void FormatError(LPCTSTR fmt, ...) { va_list arg; va_start(arg, fmt); int n = _vscprintf(fmt, arg); if(n > 0) { CHAR tmpMsg[MAX_PRINTF_MSG_LEN] = {0}; vsprintf_s(tmpMsg, MAX_PRINTF_MSG_LEN, fmt, arg); #ifdef INSERT_CONTEXT if(strlen(g_szDevName) <= 0) { CHAR szProcess[12] = {0}; sprintf_s(szProcess, "%d", GetCurrentProcessId()); WRITE_ERROR_PARAM("[%12s] %s", szProcess, tmpMsg); } else { WRITE_ERROR_PARAM("[%12s] %s", g_szDevName, tmpMsg); } #else WRITE_ERROR_PARAM("%s", tmpMsg); #endif // INSERT_CONTEXT } va_end(arg); } void FormatInfo(LPCTSTR fmt, ...) { va_list arg; va_start(arg, fmt); int n = _vscprintf(fmt, arg); if(n > 0) { CHAR tmpMsg[MAX_PRINTF_MSG_LEN] = {0}; vsprintf_s(tmpMsg, MAX_PRINTF_MSG_LEN, fmt, arg); #ifdef INSERT_CONTEXT if(strlen(g_szDevName) <= 0) { CHAR szProcess[12] = {0}; sprintf_s(szProcess, "%d", GetCurrentProcessId()); WRITE_INFO_PARAM("[%12s] %s", szProcess, tmpMsg); } else { WRITE_INFO_PARAM("[%12s] %s", g_szDevName, tmpMsg); } #else WRITE_INFO_PARAM("%s", tmpMsg); #endif // INSERT_CONTEXT } va_end(arg); } void PrintError(LPCTSTR errDesc, BOOL bGetLastError) { if(bGetLastError) { DWORD dwErrCode = GetLastError(); LPCTSTR errMsg = ErrorMessage(dwErrCode); #ifdef INSERT_CONTEXT if(strlen(g_szDevName) <= 0) { CHAR szProcess[12] = {0}; sprintf_s(szProcess, "%d", GetCurrentProcessId()); WRITE_ERROR_PARAM(TEXT("[%12s] %s: %s(%d)."), szProcess, errDesc, errMsg, dwErrCode); } else { WRITE_ERROR_PARAM(TEXT("[%12s] %s: %s(%d)."), g_szDevName, errDesc, errMsg, dwErrCode); } #else WRITE_ERROR_PARAM(TEXT("%s: %s(%d)."), errDesc, errMsg, dwErrCode); #endif // INSERT_CONTEXT LocalFree((LPVOID)errMsg); return; } #ifdef INSERT_CONTEXT if(strlen(g_szDevName) <= 0) { CHAR szProcess[12] = {0}; sprintf_s(szProcess, "%d", GetCurrentProcessId()); WRITE_ERROR_PARAM(TEXT("[%12s] %s"), szProcess, errDesc); } else { WRITE_ERROR_PARAM(TEXT("[%12s] %s"), g_szDevName, errDesc); } #else WRITE_ERROR_PARAM(TEXT("%s"), errDesc); #endif // INSERT_CONTEXT } void PrintInfo(LPCTSTR inforDesc) { #ifdef INSERT_CONTEXT if(strlen(g_szDevName) <= 0) { CHAR szProcess[12] = {0}; sprintf_s(szProcess, "%d", GetCurrentProcessId()); WRITE_INFO_PARAM(TEXT("[%12s] %s"), szProcess, inforDesc); } else { WRITE_INFO_PARAM(TEXT("[%12s] %s"), g_szDevName, inforDesc); } #else WRITE_INFO_PARAM(TEXT("%s"), inforDesc); #endif // INSERT_CONTEXT } LONG FilterException(PEXCEPTION_POINTERS pep) { // Assume we recognize this exception and then Gobal unwind LONG lDisposition = EXCEPTION_EXECUTE_HANDLER; DWORD dwCode = pep->ExceptionRecord->ExceptionCode; g_dwEceptionCode = dwCode; FormatError("ExceptionCode: 0x%08x(%d).", dwCode, dwCode); switch (dwCode) { case EXCEPTION_ACCESS_VIOLATION: PrintError("EXCEPTION_ACCESS_VIOLATION", FALSE); break; case EXCEPTION_STACK_OVERFLOW: PrintError("EXCEPTION_STACK_OVERFLOW", FALSE); break; case EXCEPTION_INVALID_HANDLE: PrintError("EXCEPTION_INVALID_HANDLE", FALSE); break; default: // We don't recognize this exception lDisposition = EXCEPTION_CONTINUE_SEARCH; break; } // temporary --Josephus at 18:01:15 201726 //lDisposition = EXCEPTION_CONTINUE_SEARCH; return (lDisposition); } void InitLogger(LPCTSTR lpszDbgPath/* = NULL*/) { //log initialize. char szLogPath[MAX_PATH] = {0}; if(lpszDbgPath == NULL) { // -Josephus@201773 17:16:07 if(GetCurrentRVCPath(szLogPath) < 0) { GET_LOGGER()->SetWriteAbleLevel(LEVEL_NONE_WRITEABLE); //PWSTR pszPath = NULL; //if(SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, NULL, &pszPath) != S_OK) //{ // GET_LOGGER()->SetWriteAbleLevel(LEVEL_NONE_WRITEABLE); //} //else //{ // WideCharToMultiByte(CP_ACP, 0, pszPath, -1, szLogPath, MAX_PATH, NULL, NULL); // CoTaskMemFree((LPVOID)pszPath); // strcat_s(szLogPath, MAX_PATH, "\\SpBranch"); //} } else { strcat_s(szLogPath, MAX_PATH, "dbg\\SpBranch"); // Check for existence and have write permssion or not. if( (_access(szLogPath, 0 )) == -1 || (_access(szLogPath, 2 )) == -1) { GET_LOGGER()->SetWriteAbleLevel(LEVEL_NONE_WRITEABLE); } else { GET_LOGGER()->SetFileWriteMode(Day_Seperated_Mode, (LPCTSTR)szLogPath); } } } else { strcpy_s(szLogPath, lpszDbgPath); // Check for existence and have write permssion or not. if( (_access(szLogPath, 0 )) == -1 || (_access(szLogPath, 2 )) == -1) { GET_LOGGER()->SetWriteAbleLevel(LEVEL_NONE_WRITEABLE); } else { GET_LOGGER()->SetFileWriteMode(Day_Seperated_Mode, (LPCTSTR)szLogPath); } } //log initialize end. return; } int _tmain(int argc, _TCHAR* argv[]) { if(argc < 2 || strlen(argv[1]) <= 0 || strlen(argv[2]) <= 0) { ExitProcess(1); } // Install our global unhandled exception filter when // creating the first instance of the class. pfnUnhandledExceptionFilterPrev = SetUnhandledExceptionFilter(CustomUnhandleExceptionFilter); BOOL bSuc = FALSE; HANDLE hStdin, hStdout; hStdout = GetStdHandle(STD_OUTPUT_HANDLE); hStdin = GetStdHandle(STD_INPUT_HANDLE); memset(g_szDevName, 0, sizeof(CHAR)*MAX_PATH); strcpy_s(g_szDevName, MAX_PATH, argv[2]); if(argc == 4 && strlen(argv[3]) > 0) { InitLogger(argv[3]); } else { InitLogger(); } FormatInfo(" ============ Branch device child process start!============ processId = %u", GetCurrentProcessId()); int nLevel = 0; ShowProcessIntegrityLevel(&nLevel); if ((hStdout == INVALID_HANDLE_VALUE) || (hStdin == INVALID_HANDLE_VALUE)) { FormatError("GetStdHandle failed, out(%d), in(%d).", hStdout, hStdin); ExitProcess(1); } char szAdapterDir[MAX_PATH] = {0}; char szAdapterPath[MAX_PATH] = {0}; if(GetCurrentRunPath(szAdapterDir) < 0) { FormatError("GetCurrentRunPath failed."); ExitProcess(1); } sprintf_s(szAdapterPath, MAX_PATH, "%sIMDep\\%s", szAdapterDir, argv[1]); __try { //LoadLibrary and Init Entity. PrintInfo("LoadLibrary and Init Entity."); gSpBranch.Init(szAdapterPath, argv[2]); } __finally { PrintInfo("LoadLibrary and Init Entity finished."); } //g_hHeap = GetProcessHeap(); g_pbtRequest = (BYTE*)HeapAlloc(GetProcessHeap(), 0, BUFSIZE*sizeof(BYTE)); g_pbtReply = (BYTE*)HeapAlloc(GetProcessHeap(), 0, BUFSIZE*sizeof(BYTE)); DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0; if (g_pbtRequest == NULL || g_pbtReply == NULL) { PrintError("HeapAlloc failed for exchange buffer"); CustomExitProcess(1); } ErrorCodeEnum erroCode = Error_Unexpect; PrintInfo("** This is a exchange circle start from the child process."); for (;;) { // Read from standard input and stop on error or no data. PrintInfo(">>=>>=>> Waiting for request information from server..."); bSuc = ReadFile( hStdin, // handle to pipe g_pbtRequest, // buffer to receive data BUFSIZE*sizeof(BYTE), // size of buffer &cbBytesRead, // number of bytes read NULL); // not overlapped I/O if (! bSuc || cbBytesRead == 0) { if(GetLastError() == ERROR_BROKEN_PIPE) { PrintError("Client disconnected"); } else { PrintError("ReadFile operation failed"); } break; } __try { ZeroMemory(g_pbtReply, BUFSIZE*sizeof(BYTE)); cbReplyBytes = GetAnswerToRequest(g_pbtRequest, cbBytesRead, g_pbtReply); ZeroMemory(g_pbtRequest, BUFSIZE*sizeof(BYTE)); } __except(FilterException(GetExceptionInformation())) { PrintError("GetAnswerToRequest appears exception.", FALSE); cbReplyBytes = SetExceptionCodeToReply(g_pbtReply); } PrintInfo("Start to WriteFiles..."); bSuc = WriteFile( hStdout, // handle to pipe g_pbtReply, // buffer to write from cbReplyBytes, // number of bytes to write &cbWritten, // number of bytes written NULL); // not overlapped I/O if (! bSuc || cbReplyBytes != cbWritten) { PrintError("WriteFile operation failed"); break; } FormatInfo("WriteFile suc, had been written %d bytes.", cbWritten); } CleanupProcess(); return 0; } int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(hInstance); return _tmain(__argc, __argv); } DWORD GetAnswerToRequest( LPBYTE pbtRequest, DWORD dwRead, LPBYTE pbtReply) { CAutoBuffer rvcBuf; //For CAutoBuffer when its destoryed. BYTE* btTmp = new BYTE[BUFSIZE]; if(btTmp == NULL) { SpBranch_Command_Ans ans; ans.Init(); ans.dwErroCode = Error_Resource; ans.desc = "Allocate buffer for request command failed in spbranch."; FormatError("Allocate buffer for request command failed"); CAutoBuffer ansBuf = SpObject2Buffer(ans); CopyMemory(pbtReply, ansBuf.GetWriteableArray(), ansBuf.GetCount()); return (sizeof(BYTE)*(ansBuf.GetCount())); } ZeroMemory(btTmp, BUFSIZE); CopyMemory(btTmp, pbtRequest, dwRead); rvcBuf.Attach(btTmp, dwRead); SpBranch_Command_Req req; SpBuffer2Object(rvcBuf, req); FormatInfo("Request Information : Size#%u, CmdType: %s(%d)", dwRead, CmdTypeToString((CMDType)req.nCmdType), req.nCmdType); SpBranch_Command_Ans ans; ans.Init(); ErrorCodeEnum erroCode = Error_Unexpect; DevThreadState eCurState = gSpBranch.GetDevThreadState(); if(gSpBranch.GetDevThreadState() < State_LoadSucc && req.nCmdType != BRCMD_GETSTATE) { FormatError("Current dev's state is invalid: %s.", DevStateToString(eCurState)); ans.nparam1 = eCurState; ans.nparam2 = gSpBranch.GetLastErrorCode(); ans.dwErroCode = Error_DevLoadFileFailed; gSpBranch.GetLastErrorMsg(ans.desc); } else { switch (req.nCmdType) { case BRCMD_SENDCMD: { CSimpleStringA ssRetString; if(gSpBranch.ExecuteCmd(req.ssparam1, ssRetString)) { ans.dwErroCode = Error_Succeed; ans.nparam1 = 0; ans.ssparam1 = ssRetString; char szPrintMsg[MAX_PRINTF_MSG_LEN] = {0}; CovertCmdParam(szPrintMsg, (LPCTSTR)req.ssparam1); FormatInfo("[param:%s] ExecuteCmd suc.", szPrintMsg); } else { char szPrintMsg[MAX_PRINTF_MSG_LEN] = {0}; CovertCmdParam(szPrintMsg, (LPCTSTR)req.ssparam1); FormatError("[param:%s] ExecuteCmd failed returned 0x%08x", szPrintMsg, gSpBranch.GetLastErrorCode()); gSpBranch.GetLastOperatError(ans.dwErroCode, ans.desc); } } break; case BRCMD_GETSTATE: { ans.dwErroCode = Error_Succeed; ans.nparam1 = eCurState; FormatInfo("GetState: state#%d.", ans.nparam1); } break; case BRCMD_OPENDEV: { if(gSpBranch.OpenDevice(req.ssparam1, req.ssparam2)) { ans.dwErroCode = Error_Succeed; } else { gSpBranch.GetLastOperatError(ans.dwErroCode, ans.desc); } } break; case BRCMD_CLOSEDEV: { if(gSpBranch.CloseDevice()) { ans.dwErroCode = Error_Succeed; } else { gSpBranch.GetLastOperatError(ans.dwErroCode, ans.desc); } } break; case BRCMD_GETERROR: { ans.dwErroCode = Error_NoPrivilege; ans.desc = "Actually its Error_NotImpl"; } break; case BRCMD_GETDEVINFO: { DevCategoryInfo info; if(gSpBranch.GetDevCategory(info)) { PrintInfo("GetDevCategory suc, start to set context."); FormatInfo("szModel:%s", info.szModel); ans.ssparam2 = info.szModel; FormatInfo("szVendor:%s", info.szVendor); ans.ssparam3 = info.szVendor; ans.nparam1 = info.eState; FormatInfo("szType:%s", info.szType); ans.ssparam1 = info.szType; FormatInfo("version:%d.%d.%d.%d", info.version.wMajor, info.version.wMinor, info.version.wRevision, info.version.wBuild); ans.ssparam4 = CSimpleStringA::Format("%d.%d.%d.%d", info.version.wMajor, info.version.wMinor, info.version.wRevision, info.version.wBuild); FormatInfo("finish setting context."); ans.dwErroCode = Error_Succeed; } else { gSpBranch.GetLastOperatError(ans.dwErroCode, ans.desc); } } break; default: { ans.dwErroCode = Error_NotExist; PrintInfo("Unexpect Command Type."); ans.desc = "Unexpect Command Type"; } break; } } CAutoBuffer ansBuf = SpObject2Buffer(ans); CopyMemory(pbtReply, ansBuf.GetWriteableArray(), ansBuf.GetCount()); return (sizeof(BYTE)*(ansBuf.GetCount())); } void CustomExitProcess(UINT uExitCode) { CleanupProcess(); FormatInfo("** The branch loaded process exitting by hand ! ProcessId = %u.", GetCurrentProcessId()); ExitProcess(uExitCode); } LONG WINAPI CustomUnhandleExceptionFilter(PEXCEPTION_POINTERS pep) { // Default to trying another filter (safest thing to do) LONG lDisposition = EXCEPTION_CONTINUE_SEARCH; // If no node fixed the problem, try the previous exception filter if (lDisposition == EXCEPTION_CONTINUE_SEARCH) { CleanupProcess(); lDisposition = pfnUnhandledExceptionFilterPrev(pep); } return(lDisposition); } void CleanupProcess() { if (g_pbtRequest != NULL) { HeapFree(GetProcessHeap(), 0, g_pbtRequest); g_pbtRequest = NULL; } if(g_pbtReply != NULL) { HeapFree(GetProcessHeap(), 0, g_pbtReply); g_pbtReply = NULL; } } DWORD SetExceptionCodeToReply(LPBYTE pbtReply) { SpBranch_Command_Ans ans; ans.Init(); ans.nparam1 = (int)(g_dwEceptionCode & 0x0000FFFF); ans.nparam2 = (int)((g_dwEceptionCode & 0xFFFF0000) >> 16); ans.dwErroCode = Error_Exception; ans.desc = "Current operation occurs exception."; CAutoBuffer ansBuf = SpObject2Buffer(ans); CopyMemory(pbtReply, ansBuf.GetWriteableArray(), ansBuf.GetCount()); return (sizeof(BYTE)*(ansBuf.GetCount())); } void ShowProcessIntegrityLevel(int* pIntegrityLevel) { HANDLE hToken; HANDLE hProcess; DWORD dwLengthNeeded; DWORD dwError = ERROR_SUCCESS; PTOKEN_MANDATORY_LABEL pTIL = NULL; LPWSTR pStringSid; DWORD dwIntegrityLevel; hProcess = GetCurrentProcess(); if (OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &hToken)) { // Get the Integrity level. if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwLengthNeeded)) { dwError = GetLastError(); if (dwError == ERROR_INSUFFICIENT_BUFFER) { pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwLengthNeeded); if (pTIL != NULL) { if (GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwLengthNeeded, &dwLengthNeeded)) { dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid)-1)); if (dwIntegrityLevel < SECURITY_MANDATORY_MEDIUM_RID) { // Low Integrity PrintInfo("Current process's Integrity: Low"); *pIntegrityLevel = 3; } else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID && dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID) { // Medium Integrity PrintInfo("Current process's Integrity: Medium"); *pIntegrityLevel = 2; } else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID) { // High Integrity PrintInfo("Current process's Integrity: High"); *pIntegrityLevel = 1; } } LocalFree(pTIL); } } } CloseHandle(hToken); } } int GetCurrentRunPath(char *pPath) { char *pBuf = new char[MAX_PATH]; if (pBuf == NULL) return -1; ZeroMemory(pBuf,MAX_PATH); GetModuleFileName(NULL,pBuf,MAX_PATH); int len = strnlen_s(pBuf,MAX_PATH); if (len <= 0) { delete []pBuf; return -2; } char *pch; pch = strstr (pBuf,"bin"); if (pch == NULL) return -3; int lenDel = strnlen_s(pch,MAX_PATH); if (len <= 0) { delete []pBuf; return -3; } strncpy_s(pPath,MAX_PATH,pBuf,len-lenDel); delete []pBuf; return strnlen_s(pPath,MAX_PATH); } int GetCurrentRVCPath(char *pPath) { char *pBuf = new char[MAX_PATH]; if (pBuf == NULL) return -1; ZeroMemory(pBuf,MAX_PATH); GetModuleFileName(NULL,pBuf,MAX_PATH); int len = strnlen_s(pBuf,MAX_PATH); if (len <= 0) { delete []pBuf; return -2; } char *pch; pch = strstr (pBuf,"bin"); if (pch == NULL) return -3; int lenDel = strnlen_s(pch,MAX_PATH); if (len <= 0) { delete []pBuf; return -3; } pBuf[1] = ':'; pBuf[2] = '\\'; pBuf[3] = '\0'; strcat_s(pBuf, MAX_PATH, "rvc\\"); strcpy_s(pPath, MAX_PATH, pBuf); delete []pBuf; return strnlen_s(pPath, MAX_PATH); pch[0] = '\0'; len = strnlen_s(pBuf, MAX_PATH); for(int i=0; i= 'A' && pBuf[i] <= 'Z') pBuf[i] += 32; } //"Run\version\1.9.0.0\bin" pch = strstr(pBuf, "version"); if(pch == NULL) { delete []pBuf; return -4; } pch[-1] = '\0'; pch = strrchr(pBuf, '\\'); if(pch == NULL) { delete []pBuf; return -5; } pch[1] = '\0'; strcat_s(pBuf, MAX_PATH, "rvc\\"); strcpy_s(pPath, MAX_PATH, pBuf); delete []pBuf; return strnlen_s(pPath, MAX_PATH); }