diff --git a/include/WinStd/Win.h b/include/WinStd/Win.h index e97299dc..80de3edb 100644 --- a/include/WinStd/Win.h +++ b/include/WinStd/Win.h @@ -40,6 +40,29 @@ template inline VOID GuidToStringW(_In_ L #else #define GuidToString GuidToStringA #endif + +/// +/// Parses string with GUID and stores it to GUID +/// +/// \param[in ] lpszGuid String with GUID +/// \param[out] lpGuid GUID to store the result to +/// +BOOL WINSTD_API StringToGuidA(_In_z_ LPCSTR lpszGuid, _Out_ LPGUID lpGuid); + +/// +/// Parses string with GUID and stores it to GUID +/// +/// \param[in ] lpszGuid String with GUID +/// \param[out] lpGuid GUID to store the result to +/// +BOOL WINSTD_API StringToGuidW(_In_z_ LPCWSTR lpszGuid, _Out_ LPGUID lpGuid); + +#ifdef _UNICODE +#define StringToGuid StringToGuidW +#else +#define StringToGuid StringToGuidA +#endif + template inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); template inline LSTATUS RegQueryStringValue(_In_ HKEY hReg, _In_z_ LPCWSTR pszName, _Out_ std::basic_string<_Elem, _Traits, _Ax> &sValue); template inline LSTATUS RegQueryValueExA(_In_ HKEY hKey, _In_opt_ LPCSTR lpValueName, __reserved LPDWORD lpReserved, _Out_opt_ LPDWORD lpType, _Out_ std::vector<_Ty, _Ax> &aData); diff --git a/src/Win.cpp b/src/Win.cpp index bae94ccf..3a051c43 100644 --- a/src/Win.cpp +++ b/src/Win.cpp @@ -21,6 +21,134 @@ #include "StdAfx.h" +////////////////////////////////////////////////////////////////////// +// StringToGuidA +////////////////////////////////////////////////////////////////////// + +BOOL WINSTD_API StringToGuidA(_In_z_ LPCSTR lpszGuid, _Out_ LPGUID lpGuid) +{ + GUID g; + LPSTR lpszEnd; + unsigned long ulTmp; + unsigned long long ullTmp; + + if (!lpszGuid || !lpGuid || *lpszGuid != '{') return FALSE; + lpszGuid++; + + g.Data1 = strtoul(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE) return FALSE; + lpszGuid = lpszEnd; + + if (*lpszGuid != '-') return FALSE; + lpszGuid++; + + ulTmp = strtoul(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE; + g.Data2 = (unsigned short)ulTmp; + lpszGuid = lpszEnd; + + if (*lpszGuid != '-') return FALSE; + lpszGuid++; + + ulTmp = strtoul(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE; + g.Data3 = (unsigned short)ulTmp; + lpszGuid = lpszEnd; + + if (*lpszGuid != '-') return FALSE; + lpszGuid++; + + ulTmp = strtoul(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE; + g.Data4[0] = (unsigned char)((ulTmp >> 8) & 0xff); + g.Data4[1] = (unsigned char)( ulTmp & 0xff); + lpszGuid = lpszEnd; + + if (*lpszGuid != '-') return FALSE; + lpszGuid++; + + ullTmp = _strtoui64(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE || ullTmp > 0xFFFFFFFFFFFF) return FALSE; + g.Data4[2] = (unsigned char)((ullTmp >> 40) & 0xff); + g.Data4[3] = (unsigned char)((ullTmp >> 32) & 0xff); + g.Data4[4] = (unsigned char)((ullTmp >> 24) & 0xff); + g.Data4[5] = (unsigned char)((ullTmp >> 16) & 0xff); + g.Data4[6] = (unsigned char)((ullTmp >> 8) & 0xff); + g.Data4[7] = (unsigned char)( ullTmp & 0xff); + lpszGuid = lpszEnd; + + if (*lpszGuid != '}') return FALSE; + lpszGuid++; + + if (*lpszGuid != 0) return FALSE; + + *lpGuid = g; + return TRUE; +} + + +BOOL WINSTD_API StringToGuidW(_In_z_ LPCWSTR lpszGuid, _Out_ LPGUID lpGuid) +{ + GUID g; + LPWSTR lpszEnd; + unsigned long ulTmp; + unsigned long long ullTmp; + + if (!lpszGuid || !lpGuid || *lpszGuid != '{') return FALSE; + lpszGuid++; + + g.Data1 = wcstoul(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE) return FALSE; + lpszGuid = lpszEnd; + + if (*lpszGuid != '-') return FALSE; + lpszGuid++; + + ulTmp = wcstoul(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE; + g.Data2 = (unsigned short)ulTmp; + lpszGuid = lpszEnd; + + if (*lpszGuid != '-') return FALSE; + lpszGuid++; + + ulTmp = wcstoul(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE; + g.Data3 = (unsigned short)ulTmp; + lpszGuid = lpszEnd; + + if (*lpszGuid != '-') return FALSE; + lpszGuid++; + + ulTmp = wcstoul(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE || ulTmp > 0xFFFF) return FALSE; + g.Data4[0] = (unsigned char)((ulTmp >> 8) & 0xff); + g.Data4[1] = (unsigned char)( ulTmp & 0xff); + lpszGuid = lpszEnd; + + if (*lpszGuid != '-') return FALSE; + lpszGuid++; + + ullTmp = _wcstoui64(lpszGuid, &lpszEnd, 16); + if (errno == ERANGE || ullTmp > 0xFFFFFFFFFFFF) return FALSE; + g.Data4[2] = (unsigned char)((ullTmp >> 40) & 0xff); + g.Data4[3] = (unsigned char)((ullTmp >> 32) & 0xff); + g.Data4[4] = (unsigned char)((ullTmp >> 24) & 0xff); + g.Data4[5] = (unsigned char)((ullTmp >> 16) & 0xff); + g.Data4[6] = (unsigned char)((ullTmp >> 8) & 0xff); + g.Data4[7] = (unsigned char)( ullTmp & 0xff); + lpszGuid = lpszEnd; + + if (*lpszGuid != '}') return FALSE; + lpszGuid++; + + if (*lpszGuid != 0) return FALSE; + + *lpGuid = g; + return TRUE; +} + + ////////////////////////////////////////////////////////////////////// // winstd::win_handle //////////////////////////////////////////////////////////////////////