int main(void){ wchar_t dest[11]; wchar_t dest2[11]; plan(9); ok(SUCCEEDED(StringCchCopyNW(dest, 11, L"test", 4)), "Copy entire string."); is_wstring(L"test", dest, "Result of copying entire string."); ok(SUCCEEDED(StringCchCopyNW(dest2, 11, dest, 11)), "Copy from buffer with additional capacity."); is_wstring(L"test", dest2, "Result of copying from buffer with additional capacity."); ok(SUCCEEDED(StringCchCopyNW(dest, 11, L"", 1)), "Copy empty string."); is_wstring(L"", dest, "Result of copying empty string."); ok(StringCchCopyNW(dest, 11, L"longer string", 12) == STRSAFE_E_INSUFFICIENT_BUFFER, "Copy a string that is too long."); is_wstring(L"longer str", dest, "Result of copying a string that is too long."); ok(StringCchCopyNW(dest, 0, L"test", 4) == STRSAFE_E_INVALID_PARAMETER, "Make sure error is thrown if cchDest is zero."); return 0; }
IFACEMETHODIMP ContextMenu::GetCommandString(UINT_PTR idCommand, UINT uFlags, LPUINT lpReserved, LPSTR pszName, UINT uMaxNameLen) { HRESULT hr = E_INVALIDARG; if (idCommand != IDM_SHAREWITHBOX) { return hr; } switch(uFlags) { case GCS_HELPTEXTA: hr = StringCchCopyNA(pszName, uMaxNameLen, HELP_A, uMaxNameLen); break; case GCS_HELPTEXTW: hr = StringCchCopyNW((LPWSTR)pszName, uMaxNameLen, HELP_W, uMaxNameLen); break; case GCS_VERBA: hr = StringCchCopyNA(pszName, uMaxNameLen, VERB_A, uMaxNameLen); break; case GCS_VERBW: hr = StringCchCopyNW((LPWSTR)pszName, uMaxNameLen, VERB_W, uMaxNameLen); break; default: hr = S_OK; break; } return hr; }
// // FUNCTION: CDrmShlExt::GetCommandString(UINT, UINT, LPUINT, // LPSTR, UINT) // // PURPOSE: If a user highlights one of the items added by a context menu // handler, the handler's IContextMenu::GetCommandString method is // called to request a Help text string that will be displayed on // the Windows Explorer status bar. This method can also be called // to request the verb string that is assigned to a command. // Either ANSI or Unicode verb strings can be requested. // IFACEMETHODIMP CDrmShlExt::GetCommandString( UINT_PTR idCommand, UINT uFlags, LPUINT lpReserved, LPSTR pszName, UINT uMaxNameLen) { HRESULT hr = E_INVALIDARG; // For the command "&Decrypt" (IDM_DECRYPT) if (idCommand == IDM_DECRYPT) { switch (uFlags) { case GCS_HELPTEXTA: hr = StringCchCopyNA(pszName, lstrlenA(pszName) / sizeof(pszName[0]), "Rights Network File Decrypter", uMaxNameLen); break; case GCS_HELPTEXTW: hr = StringCchCopyNW((LPWSTR)pszName, lstrlenW((LPWSTR)pszName) / sizeof(pszName[0]), L"Rights Network File Decrypter", uMaxNameLen); break; case GCS_VERBA: hr = StringCchCopyNA(pszName, lstrlenA(pszName) / sizeof(pszName[0]), VERB_DECRYPTA, uMaxNameLen); break; case GCS_VERBW: hr = StringCchCopyNW((LPWSTR)pszName, lstrlenW((LPWSTR)pszName) / sizeof(pszName[0]), VERB_DECRYPTW, uMaxNameLen); break; default: hr = S_OK; } } // If the command (idCommand) is not supported by this context menu // extension handler, return E_INVALIDARG. return hr; }
size_t SafeStrCopy( _In_ LPCWSTR wszSrc, _In_ size_t cchSrc, _Out_ LPWSTR wszDest, _In_ size_t cchDest) { if (cchSrc == (size_t)-1) cchSrc = wcslen(wszSrc); if (cchSrc >= cchDest) { SetLastError(ERROR_FILENAME_EXCED_RANGE); return 0; } if (FAILED(StringCchCopyNW( wszDest, cchDest, wszSrc, cchSrc))) { SetLastError(ERROR_FILENAME_EXCED_RANGE); return 0; } return cchSrc; }
BOOL CFileDefExt::InitFilePath(HWND hwndDlg) { /* Find the filename */ WCHAR *pwszFilename = PathFindFileNameW(m_wszPath); if (pwszFilename > m_wszPath) { /* Location field */ WCHAR wszLocation[MAX_PATH]; StringCchCopyNW(wszLocation, _countof(wszLocation), m_wszPath, pwszFilename - m_wszPath); PathRemoveBackslashW(wszLocation); SetDlgItemTextW(hwndDlg, 14009, wszLocation); } /* Filename field */ SetDlgItemTextW(hwndDlg, 14001, pwszFilename); return TRUE; }
vector<KEY_NAME> GetKeysNames( _In_ PWSTR FullKeyPath ) { vector<KEY_NAME> SubKeysNames; KEY_NAME KeyName; PWSTR CurrentName; PWSTR RemainingName; ULONG Length; CurrentName = FullKeyPath; RemainingName = FullKeyPath; while (*CurrentName) { CurrentName++; RemainingName++; while (*RemainingName && (*RemainingName != L'\\')) { RemainingName++; } Length = (ULONG)(RemainingName - CurrentName); if (Length) { StringCchCopyNW(KeyName.Name, _countof(KeyName.Name), CurrentName, Length); SubKeysNames.push_back(KeyName); } CurrentName = RemainingName; } return SubKeysNames; }
DWORD WINAPI RemoveVirtualDriver ( HWND hWnd, PVIRT_DEVICE pVirtualDevice, ULONG BusNumber) { HANDLE hDevice = INVALID_HANDLE_VALUE; ULONG ulStrLen = 0; size_t retVal = 0; UCHAR BusName[16] = "\\\\.\\1394BUS"; PIEEE1394_API_REQUEST p1394ApiReq = NULL; PIEEE1394_VDEV_PNP_REQUEST pDevPnpReq = NULL; DWORD dwBytesRet = 0; DWORD dwRet = ERROR_SUCCESS; ULONG p1394ApiReqLen = 0; if (!pVirtualDevice->DeviceID) { dwRet = ERROR_INVALID_PARAMETER; goto Exit_RemoveVirtualDriver; } _itoa_s ( BusNumber, (CHAR *) &BusName[11], ((sizeof (BusName) / sizeof (BusName[0])) - (strlen((CHAR *)BusName))), 10); hDevice = OpenDevice (hWnd, (PSTR) &BusName); if (hDevice != INVALID_HANDLE_VALUE) { //taking care of NULL termination character retVal = strlen(pVirtualDevice->DeviceID) + 1; if (S_OK != (SizeTToULong (retVal, &ulStrLen))) { dwRet = GetLastError(); TRACE (TL_ERROR, (hWnd, "SizeTToULong failed: %d\n", dwRet)); goto Exit_RemoveVirtualDriver; } if ( pVirtualDevice->fulFlags & IEEE1394_REQUEST_FLAG_UNICODE ) { p1394ApiReq = \ (PIEEE1394_API_REQUEST) LocalAlloc ( LPTR, sizeof(IEEE1394_API_REQUEST)+(ulStrLen * sizeof(WCHAR))); if (NULL == p1394ApiReq) { dwRet = GetLastError(); TRACE (TL_FATAL, (hWnd, "LocalAlloc failed: %d\n", dwRet)); goto Exit_RemoveVirtualDriver; } p1394ApiReqLen = \ sizeof(IEEE1394_API_REQUEST)+(ulStrLen * sizeof(WCHAR)); } else { p1394ApiReq = (PIEEE1394_API_REQUEST) LocalAlloc ( LPTR, sizeof(IEEE1394_API_REQUEST)+ulStrLen); if (NULL == p1394ApiReq) { dwRet = GetLastError(); TRACE (TL_FATAL, (hWnd, "LocalAlloc failed: %d\n", dwRet)); goto Exit_RemoveVirtualDriver; } p1394ApiReqLen = sizeof(IEEE1394_API_REQUEST)+ ulStrLen; } p1394ApiReq->RequestNumber = IEEE1394_API_REMOVE_VIRTUAL_DEVICE; p1394ApiReq->Flags = 0; pDevPnpReq = &p1394ApiReq->u.RemoveVirtualDevice; pDevPnpReq->fulFlags = pVirtualDevice->fulFlags; pDevPnpReq->Reserved = 0; pDevPnpReq->InstanceId = pVirtualDevice->InstanceID; if (pVirtualDevice->fulFlags & IEEE1394_REQUEST_FLAG_UNICODE) { if (S_OK != StringCchCopyNW ( (LPWSTR)&pDevPnpReq->DeviceId, ulStrLen, (LPWSTR)pVirtualDevice->DeviceID, ulStrLen)) { TRACE (TL_FATAL, (hWnd, "StringCchCopyNW failed\n")); dwRet = ERROR_INSUFFICIENT_BUFFER; goto Exit_RemoveVirtualDriver; } if (!DeviceIoControl ( hDevice, IOCTL_IEEE1394_API_REQUEST, p1394ApiReq, p1394ApiReqLen, NULL, 0, &dwBytesRet, NULL)) { dwRet = GetLastError(); goto Exit_RemoveVirtualDriver; } } else { if (S_OK != StringCchCopyNA ( (STRSAFE_LPSTR) &pDevPnpReq->DeviceId, ulStrLen, (STRSAFE_LPSTR) pVirtualDevice->DeviceID, ulStrLen)) { TRACE (TL_FATAL, (hWnd, "StringCchCopyNA failed\n")); dwRet = ERROR_INSUFFICIENT_BUFFER; goto Exit_RemoveVirtualDriver; } if (!DeviceIoControl ( hDevice, IOCTL_IEEE1394_API_REQUEST, p1394ApiReq, p1394ApiReqLen, NULL, 0, &dwBytesRet, NULL)) { dwRet = GetLastError(); } } } else { dwRet = ERROR_INVALID_HANDLE; } Exit_RemoveVirtualDriver: if (INVALID_HANDLE_VALUE != hDevice) { CloseHandle (hDevice); } if (p1394ApiReq) { LocalFree (p1394ApiReq); } return dwRet; }
DWORD WINAPI AddVirtualDriver ( HWND hWnd, PVIRT_DEVICE pVirtualDevice, ULONG BusNumber) { HANDLE hDevice; ULONG ulStrLen; size_t retVal = 0; UCHAR BusName[16] = "\\\\.\\1394BUS"; PIEEE1394_API_REQUEST p1394ApiReq; PIEEE1394_VDEV_PNP_REQUEST pDevPnpReq; DWORD dwBytesRet; DWORD dwRet; ULONG p1394ApiReqLen = 0; TRACE(TL_TRACE, (hWnd, "AddVirtual Driver\r\n")); _itoa_s ( BusNumber, (CHAR *) &BusName[11], ((sizeof (BusName) / sizeof (BusName[0])) - (strlen((CHAR *)BusName))), 10); TRACE (TL_TRACE, (hWnd, "Bus: %s\r\n", BusName)); hDevice = OpenDevice (hWnd, (PSTR) &BusName); if (hDevice != INVALID_HANDLE_VALUE) { //taking care of NULL terminating character retVal = strlen(pVirtualDevice->DeviceID) + 1; if (S_OK != (SizeTToULong (retVal, &ulStrLen))) { dwRet = GetLastError(); TRACE (TL_ERROR, (hWnd, "SizeTToULong failed: %d\n", dwRet)); return dwRet; } if ( pVirtualDevice->fulFlags & IEEE1394_REQUEST_FLAG_UNICODE ) { p1394ApiReq = (PIEEE1394_API_REQUEST) LocalAlloc ( LPTR, sizeof(IEEE1394_API_REQUEST)+(ulStrLen * sizeof(WCHAR))); if (NULL == p1394ApiReq) { DWORD gle = GetLastError(); TRACE (TL_FATAL, (hWnd, "LocalAlloc failed: %d\n", gle)); return gle; } p1394ApiReqLen = \ sizeof(IEEE1394_API_REQUEST)+(ulStrLen * sizeof(WCHAR)); } else { p1394ApiReq = (PIEEE1394_API_REQUEST) LocalAlloc(LPTR, sizeof(IEEE1394_API_REQUEST)+ulStrLen); if (NULL == p1394ApiReq) { DWORD gle = GetLastError(); TRACE (TL_FATAL, (hWnd, "LocalAlloc failed: %d\n", gle)); return gle; } p1394ApiReqLen = sizeof(IEEE1394_API_REQUEST)+ ulStrLen; } p1394ApiReq->RequestNumber = IEEE1394_API_ADD_VIRTUAL_DEVICE; p1394ApiReq->Flags = pVirtualDevice->fulFlags; pDevPnpReq = &p1394ApiReq->u.AddVirtualDevice; pDevPnpReq->fulFlags = pVirtualDevice->fulFlags; pDevPnpReq->Reserved = 0; pDevPnpReq->InstanceId = pVirtualDevice->InstanceID; if ( pVirtualDevice->fulFlags & IEEE1394_REQUEST_FLAG_UNICODE ) { if (S_OK != StringCchCopyNW ( (LPWSTR)&pDevPnpReq->DeviceId, ulStrLen, (LPWSTR)pVirtualDevice->DeviceID, ulStrLen)) { TRACE (TL_FATAL, (hWnd, "StringCchCopyNW failed\n")); return ERROR_INSUFFICIENT_BUFFER; } dwRet = DeviceIoControl ( hDevice, IOCTL_IEEE1394_API_REQUEST, p1394ApiReq, p1394ApiReqLen, NULL, 0, &dwBytesRet, NULL); } else { if (S_OK != StringCchCopyNA ( (STRSAFE_LPSTR) &pDevPnpReq->DeviceId, ulStrLen, (STRSAFE_LPSTR) pVirtualDevice->DeviceID, ulStrLen)) { TRACE (TL_FATAL, (hWnd, "StringCchCopyNA failed\n")); return ERROR_INSUFFICIENT_BUFFER; } dwRet = DeviceIoControl ( hDevice, IOCTL_IEEE1394_API_REQUEST, p1394ApiReq, p1394ApiReqLen, NULL, 0, &dwBytesRet, NULL); } if (!dwRet) { dwRet = GetLastError(); TRACE( TL_WARNING, (hWnd, "Failed IOCTL_IEEE1394_API_REQEST 0x%x\r\n", dwRet)); } else { TRACE(TL_WARNING, (hWnd, "Succeeded IOCTL_IEEE1394_API_REQEST\r\n")); dwRet = ERROR_SUCCESS; } // free resources CloseHandle (hDevice); LocalFree(p1394ApiReq); } else { dwRet = ERROR_INVALID_HANDLE; } return dwRet; }
HRESULT StringCchCopyW( LPWSTR pszDest, size_t cchDest, LPCWSTR pszSrc){ return StringCchCopyNW(pszDest, cchDest, pszSrc, cchDest); }
BOOL WINAPI CreateEnvironmentBlock(OUT LPVOID *lpEnvironment, IN HANDLE hToken, IN BOOL bInherit) { NTSTATUS Status; LONG lError; PWSTR* Environment = (PWSTR*)lpEnvironment; DWORD Length; DWORD dwType; HKEY hKey; HKEY hKeyUser; LPWSTR lpUserName = NULL; LPWSTR lpDomainName = NULL; WCHAR Buffer[MAX_PATH]; WCHAR szValue[1024]; DPRINT("CreateEnvironmentBlock() called\n"); if (lpEnvironment == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } Status = RtlCreateEnvironment((BOOLEAN)bInherit, Environment); if (!NT_SUCCESS(Status)) { DPRINT1("RtlCreateEnvironment() failed (Status %lx)\n", Status); SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } /* Set 'SystemRoot' variable */ Length = ARRAYSIZE(Buffer); if (GetEnvironmentVariableW(L"SystemRoot", Buffer, Length)) { SetUserEnvironmentVariable(Environment, L"SystemRoot", Buffer, FALSE); } /* Set 'SystemDrive' variable */ if (GetEnvironmentVariableW(L"SystemDrive", Buffer, Length)) { SetUserEnvironmentVariable(Environment, L"SystemDrive", Buffer, FALSE); } /* Set variables from Session Manager */ if (!SetSystemEnvironment(Environment)) { RtlDestroyEnvironment(*Environment); return FALSE; } /* Set 'COMPUTERNAME' variable */ Length = ARRAYSIZE(Buffer); if (GetComputerNameW(Buffer, &Length)) { SetUserEnvironmentVariable(Environment, L"COMPUTERNAME", Buffer, FALSE); } /* Set 'ALLUSERSPROFILE' variable */ Length = ARRAYSIZE(Buffer); if (GetAllUsersProfileDirectoryW(Buffer, &Length)) { SetUserEnvironmentVariable(Environment, L"ALLUSERSPROFILE", Buffer, FALSE); } /* Set 'USERPROFILE' variable to the default users profile */ Length = ARRAYSIZE(Buffer); if (GetDefaultUserProfileDirectoryW(Buffer, &Length)) { SetUserEnvironmentVariable(Environment, L"USERPROFILE", Buffer, TRUE); } lError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, &hKey); if (lError == ERROR_SUCCESS) { Length = sizeof(szValue); lError = RegQueryValueExW(hKey, L"ProgramFilesDir", NULL, &dwType, (LPBYTE)szValue, &Length); if (lError == ERROR_SUCCESS) { SetUserEnvironmentVariable(Environment, L"ProgramFiles", szValue, FALSE); } Length = sizeof(szValue); lError = RegQueryValueExW(hKey, L"CommonFilesDir", NULL, &dwType, (LPBYTE)szValue, &Length); if (lError == ERROR_SUCCESS) { SetUserEnvironmentVariable(Environment, L"CommonProgramFiles", szValue, FALSE); } RegCloseKey(hKey); } /* * If no user token is specified, the system environment variables are set * and we stop here, otherwise continue setting the user-specific variables. */ if (hToken == NULL) return TRUE; hKeyUser = GetCurrentUserKey(hToken); if (hKeyUser == NULL) { DPRINT1("GetCurrentUserKey() failed\n"); RtlDestroyEnvironment(*Environment); return FALSE; } /* Set 'USERPROFILE' variable */ Length = ARRAYSIZE(Buffer); if (GetUserProfileDirectoryW(hToken, Buffer, &Length)) { DWORD MinLen = 2; SetUserEnvironmentVariable(Environment, L"USERPROFILE", Buffer, FALSE); // FIXME: Strangely enough the following two environment variables // are not set by userenv.dll in Windows... See r68284 / CORE-9875 // FIXME2: This is done by msgina.dll !! /* At least <drive letter>:<path> */ if (Length > MinLen) { /* Set 'HOMEDRIVE' variable */ StringCchCopyNW(szValue, ARRAYSIZE(Buffer), Buffer, MinLen); SetUserEnvironmentVariable(Environment, L"HOMEDRIVE", szValue, FALSE); /* Set 'HOMEPATH' variable */ StringCchCopyNW(szValue, ARRAYSIZE(Buffer), Buffer + MinLen, Length - MinLen); SetUserEnvironmentVariable(Environment, L"HOMEPATH", szValue, FALSE); } } else { DPRINT1("GetUserProfileDirectoryW failed with error %lu\n", GetLastError()); } if (GetUserAndDomainName(hToken, &lpUserName, &lpDomainName)) { /* Set 'USERNAME' variable */ SetUserEnvironmentVariable(Environment, L"USERNAME", lpUserName, FALSE); /* Set 'USERDOMAIN' variable */ SetUserEnvironmentVariable(Environment, L"USERDOMAIN", lpDomainName, FALSE); if (lpUserName != NULL) LocalFree(lpUserName); if (lpDomainName != NULL) LocalFree(lpDomainName); } /* Set user environment variables */ SetUserEnvironment(Environment, hKeyUser, L"Environment"); /* Set user volatile environment variables */ SetUserEnvironment(Environment, hKeyUser, L"Volatile Environment"); RegCloseKey(hKeyUser); 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; }