IFACEMETHODIMP OCContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici) { if (pici->cbSize == sizeof(CMINVOKECOMMANDINFOEX) && (pici->fMask & CMIC_MASK_UNICODE)) { return E_FAIL; } return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0)); if (HIWORD(((CMINVOKECOMMANDINFOEX *)pici)->lpVerbW)) { if (StrCmpIW(((CMINVOKECOMMANDINFOEX *)pici)->lpVerbW, m_pwszVerb)) { return E_FAIL; } } if (LOWORD(pici->lpVerb) != IDM_SHARE) { return E_FAIL; } MessageBox(pici->hwnd, L"ownCloud was here", L"ownCloud was here", MB_OK | MB_ICONINFORMATION); }
static void test_assoc_one(const struct assoc_test_struct* test) { LPWSTR extension, type_expected, type_returned; PERCEIVED perceived; HRESULT hr; INT flags; /* if SHStrDupA receives a nullptr as input, it will null the output */ SHStrDupA(test->extension, &extension); SHStrDupA(test->type, &type_expected); perceived = 0xdeadbeef; flags = 0xdeadbeef; hr = pAssocGetPerceivedType(extension, &perceived, &flags, NULL); expect_hr(type_expected ? S_OK : test->hr, hr); ok(perceived == test->perceived, "%s: got perceived 0x%x, expected 0x%x\n", test->extension, perceived, test->perceived); ok(flags == test->flags, "%s: got flags 0x%x, expected 0x%x\n", test->extension, flags, test->flags); type_returned = (void *)0xdeadbeef; perceived = 0xdeadbeef; flags = 0xdeadbeef; hr = pAssocGetPerceivedType(extension, &perceived, &flags, &type_returned); expect_hr(type_expected ? S_OK : test->hr, hr); ok(perceived == test->perceived, "%s: got perceived 0x%x, expected 0x%x\n", test->extension, perceived, test->perceived); ok(flags == test->flags, "%s: got flags 0x%x, expected 0x%x\n", test->extension, flags, test->flags); if (!type_expected) { ok(type_returned == (void *)0xdeadbeef || broken(type_returned == NULL) /* Win 8 */, "%s: got type %p, expected 0xdeadbeef\n", test->extension, type_returned); } else if (type_returned == (void *)0xdeadbeef) { ok(type_returned != (void *)0xdeadbeef, "%s: got type %p, expected '%s'\n", test->extension, type_returned, test->type); } else { ok(StrCmpIW(type_expected, type_returned) == 0, "%s: got type %s, expected '%s'\n", test->extension, wine_dbgstr_w(type_returned), test->type); } CoTaskMemFree(type_returned); CoTaskMemFree(extension); CoTaskMemFree(type_expected); }
HRESULT CBoxView::FindInputFilters(void** gottaFilter, const GUID DeviceCategory) { CComPtr<ICreateDevEnum> pSysDevEnum; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum); if (FAILED(hr)) return hr; CComPtr<IEnumMoniker> pEnumCat; hr = pSysDevEnum->CreateClassEnumerator(DeviceCategory, &pEnumCat, 0); if (FAILED(hr) || pEnumCat == NULL) return hr; while (TRUE) { CComPtr<IMoniker> pMoniker; ULONG cFetched; hr = pEnumCat->Next(1, &pMoniker, &cFetched); if (hr != S_OK) //不应该用FAILED()来判断 break; LPOLESTR strName = NULL; hr = pMoniker->GetDisplayName(NULL, NULL, &strName); CComPtr<IPropertyBag> pPropBag; hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag); if (FAILED(hr)) continue; CComVariant varProp; if (DeviceCategory == CLSID_VideoInputDeviceCategory) { hr = pPropBag->Read(L"DevicePath", &varProp, 0); //视频设备有这个属性,能看到vid和pid,比较容易认 if (FAILED(hr) || StrCmpIW(varProp.bstrVal, m_szCableName.c_str()) != 0) continue; } else { hr = pPropBag->Read(L"FriendlyName", &varProp, 0); //音频设备只有类似于这样的名字:“麦克风 (6- USB 2.0 Camera)”。不太容易辨认和区分 if (FAILED(hr) || StrStrW(varProp.bstrVal, L"USB 2.0 Camera") == NULL) continue; } hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, gottaFilter); if (SUCCEEDED(hr)) return TRUE; } return S_FALSE; }
BOOL ArgToCategory(PCWSTR pszCat, KF_CATEGORY *pCategory) { *pCategory = (KF_CATEGORY)0; BOOL fSuccess = FALSE; for (int i = 0; i < ARRAYSIZE(c_rgKFCategoryMap); ++i) { if (0 == StrCmpIW(pszCat, c_rgKFCategoryMap[i].pszCategoryName)) { *pCategory = c_rgKFCategoryMap[i].category; fSuccess = TRUE; break; } } return fSuccess; }
BOOL ArgToFlag(PCWSTR pszCat, KF_DEFINITION_FLAGS *pFlags) { *pFlags = (KF_DEFINITION_FLAGS)0; BOOL fSuccess = FALSE; for (int i = 0; i < ARRAYSIZE(c_rgKFFlagMap); ++i) { if (0 == StrCmpIW(pszCat, c_rgKFFlagMap[i].pszFlagName)) { *pFlags = c_rgKFFlagMap[i].flags; fSuccess = TRUE; break; } } return fSuccess; }
BOOL CALLBACK MY_WNDENUMPROC(HWND hWnd, LPARAM lParam) { WCHAR szClassName[MAX_PATH]; GetClassName(hWnd,szClassName,MAX_PATH); if ( StrCmpIW(szClassName,L"subWin") == 0 ) { HWND *pWnd = (HWND *)lParam; if (pWnd) { *pWnd = GetParent(hWnd); } return FALSE; } return TRUE; }
STDMETHODIMP ContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) { BOOL fEx = FALSE; BOOL fUnicode = FALSE; if(lpcmi->cbSize == sizeof(CMINVOKECOMMANDINFOEX)) { fEx = TRUE; if((lpcmi->fMask & CMIC_MASK_UNICODE)) { fUnicode = TRUE; } } if( !fUnicode && HIWORD(lpcmi->lpVerb)) { if(StrCmpIA(lpcmi->lpVerb, VERB_A)) { return E_FAIL; } } else if( fUnicode && HIWORD(((CMINVOKECOMMANDINFOEX *) lpcmi)->lpVerbW)) { if(StrCmpIW(((CMINVOKECOMMANDINFOEX *)lpcmi)->lpVerbW, VERB_W)) { return E_FAIL; } } else if(LOWORD(lpcmi->lpVerb) != IDM_SHAREWITHBOX) { return E_FAIL; } else { if (m_pdtobj) { return ShareWithBoxItems(m_pdtobj, lpcmi->hwnd); } } return S_OK; }
BOOL CNetInstall::CheckFile(LPCWSTR lpszPath, tagFileInfo* pInfo) { BOOL bRet = FALSE; if (StrCmpIW(PathFindExtensionW(lpszPath), L".cia")) { return FALSE; } HANDLE hFile = CreateFileW(lpszPath, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile != INVALID_HANDLE_VALUE) { LARGE_INTEGER LargeInt; if (GetFileSizeEx(hFile, &LargeInt)) { if (pInfo) { pInfo->uFileSize = LargeInt.QuadPart; pInfo->strPath = lpszPath; bRet = TRUE; } } CloseHandle(hFile); } return bRet; }
// // FUNCTION: FileContextMenuExt::InvokeCommand // // PURPOSE: This method is called when a user clicks a menu item to tell // the handler to run the associated command. The lpcmi parameter // points to a structure that contains the needed information. // IFACEMETHODIMP FileContextMenuExt::InvokeCommand(LPCMINVOKECOMMANDINFO pici) { BOOL fUnicode = FALSE; // Determine which structure is being passed in, CMINVOKECOMMANDINFO or // CMINVOKECOMMANDINFOEX based on the cbSize member of lpcmi. Although // the lpcmi parameter is declared in Shlobj.h as a CMINVOKECOMMANDINFO // structure, in practice it often points to a CMINVOKECOMMANDINFOEX // structure. This struct is an extended version of CMINVOKECOMMANDINFO // and has additional members that allow Unicode strings to be passed. if (pici->cbSize == sizeof(CMINVOKECOMMANDINFOEX)) { if (pici->fMask & CMIC_MASK_UNICODE) { fUnicode = TRUE; } } // Determines whether the command is identified by its offset or verb. // There are two ways to identify commands: // // 1) The command's verb string // 2) The command's identifier offset // // If the high-order word of lpcmi->lpVerb (for the ANSI case) or // lpcmi->lpVerbW (for the Unicode case) is nonzero, lpVerb or lpVerbW // holds a verb string. If the high-order word is zero, the command // offset is in the low-order word of lpcmi->lpVerb. // For the ANSI case, if the high-order word is not zero, the command's // verb string is in lpcmi->lpVerb. if (!fUnicode && HIWORD(pici->lpVerb)) { // Is the verb supported by this context menu extension? if (StrCmpIA(pici->lpVerb, m_pszVerb) == 0) { OnVerbDisplayFileName(pici->hwnd); } else { // If the verb is not recognized by the context menu handler, it // must return E_FAIL to allow it to be passed on to the other // context menu handlers that might implement that verb. return E_FAIL; } } // For the Unicode case, if the high-order word is not zero, the // command's verb string is in lpcmi->lpVerbW. else if (fUnicode && HIWORD(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW)) { // Is the verb supported by this context menu extension? if (StrCmpIW(((CMINVOKECOMMANDINFOEX*)pici)->lpVerbW, m_pwszVerb) == 0) { OnVerbDisplayFileName(pici->hwnd); } else { // If the verb is not recognized by the context menu handler, it // must return E_FAIL to allow it to be passed on to the other // context menu handlers that might implement that verb. return E_FAIL; } } // If the command cannot be identified through the verb string, then // check the identifier offset. else { // Is the command identifier offset supported by this context menu // extension? if (LOWORD(pici->lpVerb) == IDM_DISPLAY) { OnVerbDisplayFileName(pici->hwnd); } else { // If the verb is not recognized by the context menu handler, it // must return E_FAIL to allow it to be passed on to the other // context menu handlers that might implement that verb. return E_FAIL; } } return S_OK; }
STDMETHODIMP CContextMenuHandler::InvokeCommand(CMINVOKECOMMANDINFO *pici) { f_log(__FUNCTION__); BOOL fEx = FALSE; BOOL fUnicode = FALSE; if (pici->cbSize = sizeof(CMINVOKECOMMANDINFOEX)) { fEx = TRUE; if ((pici->fMask & CMIC_MASK_UNICODE)) { fUnicode = TRUE; } } if (!fUnicode && HIWORD(pici->lpVerb)) { if (StrCmpIA(pici->lpVerb, szVerbRunConsoleA) == 0) { if (!sPath.IsEmpty()) { RunConsole(sPath, false); } return S_OK; } else if (StrCmpIA(pici->lpVerb, szVerbPostConsoleA) == 0) { if (!sPath.IsEmpty()) { RunConsole(sPath, true); } return S_OK; } return E_FAIL; } if (fUnicode && HIWORD(reinterpret_cast<CMINVOKECOMMANDINFOEX*>(pici)->lpVerbW)) { if (StrCmpIW(reinterpret_cast<CMINVOKECOMMANDINFOEX*>(pici)->lpVerbW, szVerbRunConsoleW) == 0) { if (!sPath.IsEmpty()) { RunConsole(sPath, false); } return S_OK; } else if (StrCmpIW(reinterpret_cast<CMINVOKECOMMANDINFOEX*>(pici)->lpVerbW, szVerbRunConsoleW) == 0) { if (!sPath.IsEmpty()) { RunConsole(sPath, true); } return S_OK; } return E_FAIL; } if (LOWORD(pici->lpVerb) == eMC_RunConsole) { // Run console with default tab if(!sPath.IsEmpty()) { RunConsole(sPath, false); } } else if (LOWORD(pici->lpVerb) == eMC_PostConsole) { // Run console with default tab if(!sPath.IsEmpty()) { RunConsole(sPath, true); } } else if (LOWORD(pici->lpVerb) >= eMC_RunConsoleWithTab && LOWORD(pici->lpVerb) < eMC_RunConsoleWithTab + 50) { // Run console with specified tab if (!sPath.IsEmpty()) { wstring sTabName; // get tab name { // synchronization syncAutoLock oLock(g_oSync); if ((LOWORD(pici->lpVerb) - eMC_RunConsoleWithTab) < (int)g_vTabs.size()) sTabName = g_vTabs[LOWORD(pici->lpVerb) - eMC_RunConsoleWithTab]->sName; } // run RunConsole(sPath, false, sTabName.c_str()); } } else if (LOWORD(pici->lpVerb) >= eMC_PostConsoleWithTab && LOWORD(pici->lpVerb) < eMC_PostConsoleWithTab + 50) { // Run console with specified tab if (!sPath.IsEmpty()) { wstring sTabName; // get tab name { // synchronization syncAutoLock oLock(g_oSync); if ((LOWORD(pici->lpVerb) - eMC_PostConsoleWithTab) < (int)g_vTabs.size()) sTabName = g_vTabs[LOWORD(pici->lpVerb) - eMC_PostConsoleWithTab]->sName; } // run RunConsole(sPath, true, sTabName.c_str()); } } return S_OK; }
BOOL VMDriverServices() { const int KnownServiceCount = 13; const TCHAR* KnownVMServices[KnownServiceCount] = { L"VBoxWddm", L"VBoxSF", //VirtualBox Shared Folders L"VBoxMouse", //VirtualBox Guest Mouse L"VBoxGuest", //VirtualBox Guest Driver L"vmci", //VMWare VMCI Bus Driver L"vmhgfs", //VMWare Host Guest Control Redirector L"vmmouse", L"vmmemctl", //VMWare Guest Memory Controller Driver L"vmusb", L"vmusbmouse", L"vmx_svga", L"vmxnet", L"vmx86" }; SC_HANDLE hSCM = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE); if (hSCM != NULL) { ENUM_SERVICE_STATUS_PROCESS* services = NULL; DWORD serviceCount = 0; if (get_services(hSCM, SERVICE_DRIVER, &services, &serviceCount)) { bool ok = true; for (DWORD i = 0; i < serviceCount; i++) { for (int s = 0; s < KnownServiceCount; s++) { if (StrCmpIW(services[i].lpServiceName, KnownVMServices[s]) == 0) { ok = false; break; } } } free(services); if (ok) { CloseServiceHandle(hSCM); return FALSE; } } else { printf("Failed to get services list.\n"); } CloseServiceHandle(hSCM); } else { printf("Failed to get SCM handle.\n"); } return TRUE; }
UINT WINAPI SHExplorerParseCmdLine(ExplorerCommandLineParseResults * pInfo) { WCHAR strField[MAX_PATH]; WCHAR strDir[MAX_PATH]; PCWSTR strCmdLine = GetCommandLineW(); PCWSTR strFieldArray = PathGetArgsW(strCmdLine); if (!*strFieldArray) { pInfo->dwFlags = 9; pInfo->pidlPath = _GetDocumentsPidl(); if (!pInfo->pidlPath) { GetWindowsDirectoryW(strDir, MAX_PATH); PathStripToRootW(strDir); pInfo->pidlPath = ILCreateFromPathW(strDir); } return (LONG) (pInfo->pidlPath); } PCWSTR strNextArg = _FindFirstField(strFieldArray); BOOL hasNext = TRUE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); while (TRUE) { // Basic flags-only params first if (!StrCmpIW(strField, L"/N")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_N | SH_EXPLORER_CMDLINE_FLAG_ONE; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/S")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_S; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/E")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_E; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/SELECT")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_SELECT; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/NOUI")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_NOUI; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"-embedding")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_EMBED; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/SEPARATE")) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_SEPARATE; TRACE("CmdLine Parser: Parsed %S flag. dwFlags=%08lx\n", strField, pInfo->dwFlags); } else if (!StrCmpIW(strField, L"/INPROC")) { // No idea what Inproc is supposed to do, but it gets a GUID, and parses it. TRACE("CmdLine Parser: Found %S flag\n", strField); if (!hasNext) return FALSE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); if (!GUIDFromStringW(strField, &(pInfo->guidInproc))) return FALSE; pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_INPROC; TRACE("CmdLine Parser: Parsed /INPROC flag. dwFlags=%08lx, guidInproc=%S\n", pInfo->dwFlags, strField); } else if (!StrCmpIW(strField, L"/ROOT")) { LPITEMIDLIST pidlRoot = NULL; // The window should be rooted TRACE("CmdLine Parser: Found %S flag\n", strField); if (!pInfo->pidlPath) return FALSE; if (!hasNext) return FALSE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); // Root may be a pidl if (!StrCmpIW(strField, L"/IDLIST")) { if (hasNext) { hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); } pidlRoot = _ILReadFromSharedMemory(strField); } else { // Or just a path string _ParsePathToPidl(strField, &pidlRoot); } pInfo->pidlRoot = pidlRoot; // The root defaults to the desktop if (!pidlRoot) { if (FAILED(SHGetSpecialFolderLocation(0, CSIDL_DESKTOP, &(pInfo->pidlRoot)))) pInfo->pidlRoot = NULL; } // TODO: Create rooted PIDL from pInfo->pidlPath and pInfo->pidlRoot TRACE("CmdLine Parser: Parsed /ROOT flag. dwFlags=%08lx, pidlRoot=%p\n", pInfo->dwFlags, pInfo->pidlRoot); } else { // Anything else is part of the target path to browse to TRACE("CmdLine Parser: Found target path %S\n", strField); // Which can be a shared-memory itemidlist if (!StrCmpIW(strField, L"/IDLIST")) { LPITEMIDLIST pidlArg; if (!hasNext) return FALSE; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); pidlArg = _ILReadFromSharedMemory(strField); if (!pidlArg) return FALSE; if (pInfo->pidlPath) ILFree(pInfo->pidlPath); pInfo->pidlPath = pidlArg; TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, pidlPath=%p\n", pInfo->dwFlags, pInfo->pidlPath); } else { // Or just a plain old string. WCHAR szPath[MAX_PATH]; DWORD result = GetFullPathNameW(strField, _countof(szPath), szPath, NULL); if (result != 0 && result <= _countof(szPath) && PathFileExistsW(szPath)) StringCchCopyW(strField, _countof(strField), szPath); LPITEMIDLIST pidlPath = ILCreateFromPathW(strField); pInfo->pidlPath = pidlPath; if (pidlPath) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_IDLIST; TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, pidlPath=%p\n", pInfo->dwFlags, pInfo->pidlPath); } else { // The path could not be parsed into an ID List, // so pass it on as a plain string. PWSTR field = StrDupW(strField); pInfo->strPath = field; if (field) { pInfo->dwFlags |= SH_EXPLORER_CMDLINE_FLAG_STRING; TRACE("CmdLine Parser: Parsed target path. dwFlags=%08lx, strPath=%S\n", pInfo->dwFlags, field); } } } } if (!hasNext) break; hasNext = _ReadNextArg(&strNextArg, strField, _countof(strField)); } return TRUE; }
int BLBS_ReadSetting() { // Init and declare variables HANDLE hFile; uint8_t make_ini = FALSE; // If this is true, use default option wchar_t* file_buf = NULL; wchar_t path_buf[MAX_PATH] = {0}; uint32_t file_size = 0; BLBS_GetIniFullPath(path_buf, sizeof(path_buf)); #ifdef _DEBUG_CONSOLE printf("[IniFile]\n%S\n\n", path_buf); #endif // _DEBUG_CONSOLE // File IO // https://msdn.microsoft.com/en-us/library/windows/desktop/bb540534%28v=vs.85%29.aspx // Open File hFile = CreateFileW(path_buf, // lpFileName GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess FILE_SHARE_READ, // dwShareMode NULL, // lpSecurityAttributes OPEN_EXISTING, // dwCreationDisposition FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes NULL); // hTemplateFile // Cannot open! Error Handling if (hFile == INVALID_HANDLE_VALUE) { // No ini file, use default opntion! if (GetLastError() == ERROR_FILE_NOT_FOUND) make_ini = TRUE; else JV_ErrorHandle(JVERR_CreateFile, TRUE); } if (make_ini) { // no BatteryLine.ini, so generate BatteryLine.ini. Note : hFile is invalid at this point uint32_t written_byte = 0; // Write default setting to file hFile = CreateFileW(path_buf, // lpFileName GENERIC_READ | GENERIC_WRITE, // dwDesiredAccess 0, // dwShareMode NULL, // lpSecurityAttributes CREATE_ALWAYS, // dwCreationDisposition FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes NULL); // hTemplateFile // Is handle is opened without problem? if (hFile == INVALID_HANDLE_VALUE) JV_ErrorHandle(JVERR_CreateFile, TRUE); // Write BOM to File if (!WriteFile(hFile, &BOM, sizeof(uint16_t), (DWORD*)&written_byte, NULL)) JV_ErrorHandle(JVERR_WriteFile, TRUE); // Is BOM written to file fully? if (written_byte != sizeof(uint16_t)) JV_ErrorHandle(JVERR_FILEIO_WRITTEN_BYTES, FALSE); // Write default setting string to File if (!WriteFile(hFile, (void*) BL_DefaultSettingStr, wcslen(BL_DefaultSettingStr) * sizeof(wchar_t), (DWORD*)&written_byte, NULL)) JV_ErrorHandle(JVERR_WriteFile, TRUE); // Is string writeen to file fully? if (written_byte != wcslen(BL_DefaultSettingStr) * sizeof(wchar_t)) JV_ErrorHandle(JVERR_FILEIO_WRITTEN_BYTES, FALSE); // Close Handle CloseHandle(hFile); // point file_buf to BL_DefaultSettingStr, no dyn alloc file_buf = BL_DefaultSettingStr; } else { // file is successfully open, read setting from file. Note : hFile is alive at this point uint32_t read_byte = 0; size_t sztmp = 0; // Get file size, and dyn allocate file_buf file_size = GetFileSize(hFile, NULL); file_buf = (wchar_t*) malloc(file_size+16); memset((void*) file_buf, 0, file_size+16); // Read from file if (!ReadFile(hFile, // hFile file_buf, // lpBuffer file_size, // nNumberOfBytesToRead (DWORD*) &read_byte, // lpNumberOfBytesRead NULL)) // lpOverlapped JV_ErrorHandle(JVERR_ReadFile, TRUE); // Is all bytes successfully read? if (read_byte != file_size) JV_ErrorHandle(JVERR_FILEIO_READ_BYTES, FALSE); // Close Handle CloseHandle(hFile); // Add \r\n at EOF sztmp = wcslen(file_buf); file_buf[sztmp] = L'\r'; file_buf[sztmp+1] = L'\n'; file_buf[sztmp+2] = L'\0'; } // Parse ini File - Too complex... wchar_t* str_cursor = NULL, *str_next = NULL; wchar_t line_token[BS_TOKEN_BUF_SIZE]; // Unicode LineFeed : \r\n (00d0 00a0) wchar_t line_rawbuf[BS_LINE_BUF_SIZE], line_buf[BS_LINE_BUF_SIZE]; size_t line_len = 0; wchar_t* equal_pos = NULL; wchar_t equal_left[BS_LINE_BUF_SIZE], equal_right[BS_LINE_BUF_SIZE]; uint8_t state_section = BS_SECTION_OFF; uint8_t color_idx = 0; BL_OPTION valid; // 01 using \r\n as token, traverse all lines in BL_SettingFile line_token[0] = L'\r'; line_token[1] = L'\n'; line_token[2] = L'\0'; // str_cursor will serve as cursor for each line str_cursor = file_buf; // 'valid' will be used to check wether these option is already set - FALSE for not set, TRUE for set ZeroMemory(&valid, sizeof(BL_OPTION)); // Parsing loop. Escape when meet EOF while (1) { // 02 Copy one line to line_rawbuf. // 02 Note that line_rawbuf contains 'raw' strings, which has tab, space, \r, \n. str_next = StrStrW(str_cursor, line_token); // Start of next line if (str_next == NULL) // No more line, EOF break; line_len = str_next - str_cursor; // Get this line's length StringCchCopyNW(line_rawbuf, BS_LINE_BUF_SIZE, str_cursor+1, line_len-1); // Copy one line to line_buf, +1 for remove first \r\n, -1 for remove last \r str_cursor = str_next + 1; // Fot next iteration, move cursor to next line // For debugging, there is too many segfaults in parsing alg! #ifdef _DEBUG_PARSING printf("line_rawbuf : %S\n", line_rawbuf); printf("state : %u\n", state_section); #endif // Finite State Machine Model // 03 line_rawbuf has [] -> start a section, represent as 'state' if (StrChrW(line_rawbuf, L'[') != NULL && StrChrW(line_rawbuf, L']') != NULL) { // Contains [ ] switch (state_section) { case BS_SECTION_OFF: if (StrStrIW(line_rawbuf, L"[General]") != NULL) state_section = BS_SECTION_GENERAL; else if (StrStrIW(line_rawbuf, L"[Color]") != NULL) state_section = BS_SECTION_COLOR; break; case BS_SECTION_GENERAL: if (StrStrIW(line_rawbuf, L"[General]") != NULL) state_section = BS_SECTION_GENERAL; else if (StrStrIW(line_rawbuf, L"[Color]") != NULL) state_section = BS_SECTION_COLOR; else state_section = BS_SECTION_OFF; break; case BS_SECTION_COLOR: if (StrStrIW(line_rawbuf, L"[General]") != NULL) state_section = BS_SECTION_GENERAL; else if (StrStrIW(line_rawbuf, L"[Color]") != NULL) state_section = BS_SECTION_COLOR; else state_section = BS_SECTION_OFF; break; } } // 04 line_rawbuf does not have [] -> remove Tab, Space, \r, \n and put into line_buf else if (line_rawbuf[0] != L'#') // This line is not comment and do not contain [] { int32_t dword = 0; uint8_t lowedge8 = 0, highedge8 = 0, r8 = 0, g8 = 0, b8 = 0; wchar_t quote_tmp[BS_TOKEN_BUF_SIZE] = {0}; wchar_t* quote_pos = NULL, *quote_next = NULL; uint32_t x = 0; // 04 Remove Tab, Space, \r, \n from line_rawbuf and put into line_buf for (uint32_t i = 0; i < line_len; i++) { if (line_rawbuf[i] == L'#') // if we meet # in the middle, ignore remnant characters break; if (line_rawbuf[i] != L'\t' && line_rawbuf[i] != L' ' && line_rawbuf[i] != L'\r' && line_rawbuf[i] != L'\n') { line_buf[x] = line_rawbuf[i]; x++; } } line_buf[x] = L'\0'; line_len = x; #ifdef _DEBUG_PARSING printf("line_buf : %S\n", line_buf); #endif switch (state_section) { case BS_SECTION_OFF: break; case BS_SECTION_GENERAL: // 05 using = as basis, cut left sting and right string. // 06 left string : which option to set? // 06 right string : how to parse right string? equal_pos = StrChrW(line_buf, L'='); if (equal_pos == NULL) // no '=' { state_section = BS_SECTION_OFF; // invalid option, think this as end of section. continue; // so ignore this line and go to next line } StringCchCopyNW(equal_left, BS_LINE_BUF_SIZE, line_buf, equal_pos-line_buf); // Copy left part StringCchCopyW(equal_right, BS_LINE_BUF_SIZE, line_buf+(equal_pos-line_buf+1)); // Copy right part if (StrCmpIW(equal_left, L"showcharge") == 0) { // {true, false} if (StrCmpIW(equal_right, L"true") == 0) option.showcharge = TRUE; else if (StrCmpIW(equal_right, L"false") == 0) option.showcharge = FALSE; else JV_ErrorHandle(JVERR_OPT_INI_INVALID_SHOWCHARGE, FALSE); valid.showcharge = TRUE; } else if (StrCmpIW(equal_left, L"monitor") == 0) { // {primary, 1, 2, ... , 32} if (StrCmpIW(equal_right, L"primary") == 0) option.monitor = BL_MON_PRIMARY; else { int32_t dword = _wtoi(equal_right); // Count Monitor's number and write to g_nMon g_nMon = 0; g_nPriMon = 0; ZeroMemory(&g_monInfo, sizeof(MONITORINFO) * BL_MAX_MONITOR); EnumDisplayMonitors(NULL, NULL, BLCB_MonEnumProc_GetFullInfo, 0); #ifdef _DEBUG_MONITOR printf("[Monitor]\nThis system has %d monitors.\n\n", g_nMon); #endif if (!(1 <= dword && dword <= BL_MAX_MONITOR)) JV_ErrorHandle(JVERR_OPT_INI_INVALID_MONITOR, FALSE); if (!(dword <= g_nMon)) // JV_ErrorHandle(JVERR_OPT_INI_NOT_EXIST_MONITOR, FALSE); option.monitor = (uint8_t) dword; } valid.monitor = TRUE; } else if (StrCmpIW(equal_left, L"position") == 0) { // {top, bottom, left, right} if (StrCmpIW(equal_right, L"top") == 0) option.position = BL_POS_TOP; else if (StrCmpIW(equal_right, L"bottom") == 0) option.position = BL_POS_BOTTOM; else if (StrCmpIW(equal_right, L"left") == 0) option.position = BL_POS_LEFT; else if (StrCmpIW(equal_right, L"right") == 0) option.position = BL_POS_RIGHT; else JV_ErrorHandle(JVERR_OPT_INI_INVALID_POSITION, FALSE); valid.position = TRUE; } else if (StrCmpIW(equal_left, L"taskbar") == 0) { // {ignore, evade} if (StrCmpIW(equal_right, L"ignore") == 0) option.taskbar = BL_TASKBAR_IGNORE; else if (StrCmpIW(equal_right, L"evade") == 0) option.taskbar = BL_TASKBAR_EVADE; else JV_ErrorHandle(JVERR_OPT_INI_INVALID_TASKBAR, FALSE); valid.taskbar = TRUE; } else if (StrCmpIW(equal_left, L"transparency") == 0) { // {0 <= number <= 255} int32_t dword = _wtoi(equal_right); if (!(0 <= dword && dword <= 255)) JV_ErrorHandle(JVERR_OPT_INI_INVALID_TRANSPARENCY, FALSE); option.transparency = (uint8_t) dword; valid.transparency = TRUE; } else if (StrCmpIW(equal_left, L"height") == 0) { // {1 <= number <= 255} int32_t dword = _wtoi(equal_right); if (!(1 <= dword && dword <= 255)) JV_ErrorHandle(JVERR_OPT_INI_INVALID_HEIGHT, FALSE); option.height = (uint8_t) dword; valid.height = TRUE; } break; case BS_SECTION_COLOR: // 05 using = as basis, cut left sting and right string. // 06 left string : which option to set? // 06 right string : how to parse right string? equal_pos = StrChrW(line_buf, L'='); if (equal_pos == NULL) // no '=' { state_section = BS_SECTION_OFF; // invalid option, think this as end of section. continue; // so ignore this line and go to next line } StringCchCopyNW(equal_left, BS_LINE_BUF_SIZE, line_buf, equal_pos-line_buf); // Copy left part StringCchCopyW(equal_right, BS_LINE_BUF_SIZE, line_buf+(equal_pos-line_buf+1)); // Copy right part if (!StrCmpIW(equal_left, L"defaultcolor")) { // Format : {R, G, B} quote_pos = equal_right; for (uint32_t i = 0; i < 3; i++) // R, G, B { quote_next = StrChrW(quote_pos, L','); if (quote_next != NULL) // , still exists { StringCchCopyNW(quote_tmp, BS_TOKEN_BUF_SIZE, quote_pos, quote_next-quote_pos); // Copy a number quote_pos = quote_next+1; // +1 for , } else // NULL, no ','! StringCchCopyW(quote_tmp, BS_TOKEN_BUF_SIZE, quote_pos); // Copy last number dword = _wtoi(quote_tmp); if (!(0 <= dword && dword <= 255)) JV_ErrorHandle(JVERR_OPT_INI_INVALID_DEFAULTCOLOR, FALSE); switch (i) { case 0: r8 = dword; break; case 1: g8 = dword; break; case 2: b8 = dword; break; } } option.defaultcolor = RGB(r8, g8, b8); valid.defaultcolor = TRUE; } else if (!StrCmpIW(equal_left, L"chargecolor")) { // Format : {R, G, B} quote_pos = equal_right; for (uint32_t i = 0; i < 3; i++) // R, G, B { quote_next = StrChrW(quote_pos, L','); if (quote_next != NULL) // , still exists { StringCchCopyNW(quote_tmp, BS_TOKEN_BUF_SIZE, quote_pos, quote_next-quote_pos); // Copy a number quote_pos = quote_next+1; // +1 for , } else // NULL, no ','! StringCchCopyW(quote_tmp, BS_TOKEN_BUF_SIZE, quote_pos); // Copy last number dword = _wtoi(quote_tmp); if (!(0 <= dword && dword <= 255)) JV_ErrorHandle(JVERR_OPT_INI_INVALID_CHARGECOLOR, FALSE); switch (i) { case 0: r8 = dword; break; case 1: g8 = dword; break; case 2: b8 = dword; break; } } option.chargecolor = RGB(r8, g8, b8); valid.chargecolor = TRUE; } else if (!StrCmpIW(equal_left, L"fullcolor")) { // Format : {R, G, B} quote_pos = equal_right; for (uint32_t i = 0; i < 3; i++) // R, G, B { quote_next = StrChrW(quote_pos, L','); if (quote_next != NULL) // , still exists { StringCchCopyNW(quote_tmp, BS_TOKEN_BUF_SIZE, quote_pos, quote_next-quote_pos); // Copy a number quote_pos = quote_next+1; // +1 for , } else // NULL, no ','! StringCchCopyW(quote_tmp, BS_TOKEN_BUF_SIZE, quote_pos); // Copy last number dword = _wtoi(quote_tmp); if (!(0 <= dword && dword <= 255)) JV_ErrorHandle(JVERR_OPT_INI_INVALID_FULLCOLOR, FALSE); switch (i) { case 0: r8 = dword; break; case 1: g8 = dword; break; case 2: b8 = dword; break; } } option.fullcolor = RGB(r8, g8, b8); valid.fullcolor = TRUE; } else if (StrCmpIW(equal_left, L"color") == 0) { // {LowEdge, HighEdge, R, G, B}, Support up to 16 thresholds quote_pos = equal_right; for (uint32_t i = 0; i < 5; i++) // R, G, B { quote_next = StrChrW(quote_pos, L','); if (quote_next != NULL) // , still exists { StringCchCopyNW(quote_tmp, BS_TOKEN_BUF_SIZE, quote_pos, quote_next-quote_pos); // Copy a number quote_pos = quote_next+1; // +1 for , } else // NULL, no ','! StringCchCopyW(quote_tmp, BS_TOKEN_BUF_SIZE, quote_pos); // Copy last number dword = _wtoi(quote_tmp); if (!(0 <= dword && dword <= 255)) JV_ErrorHandle(JVERR_OPT_INI_INVALID_COLOR, FALSE); switch (i) { case 0: lowedge8 = dword; break; case 1: highedge8 = dword; break; case 2: r8 = dword; break; case 3: g8 = dword; break; case 4: b8 = dword; break; } } if (BL_COLOR_LEVEL <= color_idx) JV_ErrorHandle(JVERR_OPT_INI_TOO_MUCH_COLOR, FALSE); option.threshold[color_idx*2+0] = lowedge8; option.threshold[color_idx*2+1] = highedge8; option.color[color_idx] = RGB(r8, g8, b8); color_idx++; } break; } } } for (uint32_t i = color_idx; i < BL_COLOR_LEVEL; i++) { option.color[i] = 0; option.threshold[2*i] = 0; option.threshold[2*i+1] = 0; } // Free allocated byte in file_buf if (file_buf != BL_DefaultSettingStr) { free(file_buf); file_buf = NULL; } // Debug print #ifdef _DEBUG_CONSOLE puts("[Setting]"); printf("showcharge = %u\n", option.showcharge); printf("monitor = %u\n", option.monitor); printf("position = %u\n", option.position); printf("taskbar = %u\n", option.taskbar); printf("transparency = %u\n", option.transparency); printf("height = %u\n", option.height); putchar('\n'); puts("[Color]"); printf("defaultcolor = %lu,%lu,%lu\n", BLU_RGB_R(option.defaultcolor), BLU_RGB_G(option.defaultcolor), BLU_RGB_B(option.defaultcolor)); printf("chargecolor = %lu,%lu,%lu\n", BLU_RGB_R(option.chargecolor), BLU_RGB_G(option.chargecolor), BLU_RGB_B(option.chargecolor)); for (uint32_t i = 0; i < BL_COLOR_LEVEL; i++) { printf("color[%02d] = %lu,%lu,%lu\n", i, BLU_RGB_R(option.color[i]), BLU_RGB_G(option.color[i]), BLU_RGB_B(option.color[i])); printf("threshold[%02d] = %u\n", 2*i, option.threshold[2*i]); printf("threshold[%02d] = %u\n", 2*i+1, option.threshold[2*i+1]); } putchar('\n'); puts("[Event]"); // For WndProcedure Debug Message #endif // Check necessary options are read successfully if (!(valid.showcharge && valid.monitor && valid.position && valid.taskbar && valid.transparency && valid.height // Section [General] && valid.defaultcolor && valid.chargecolor && valid.fullcolor)) // Section [Color] { JV_ErrorHandle(JVERR_OPT_INI_MISSING_OPTIONS, FALSE); } return 0; }