Skip to content

Commit

Permalink
Implement the fallback for api-ms-win-core-winrt-string-l1-1-0 APIs.
Browse files Browse the repository at this point in the history
  • Loading branch information
MouriNaruto committed Jun 22, 2024
1 parent 378fe4f commit 9a97c4b
Show file tree
Hide file tree
Showing 2 changed files with 214 additions and 25 deletions.
18 changes: 9 additions & 9 deletions ThunksList.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@
## api-ms-win-core-winrt-string-l1-1-0.dll
| 函数 | Fallback
| ---- | -----------
| WindowsCreateString | 不存在时,返回 E_NOTIMPL
| WindowsCreateStringReference | 不存在时,返回 E_NOTIMPL
| WindowsDeleteString | 不存在时,返回 E_NOTIMPL
| WindowsDuplicateString | 不存在时,返回 E_NOTIMPL
| WindowsGetStringLen | 不存在时,返回 E_NOTIMPL
| WindowsGetStringRawBuffer | 不存在时,返回 E_NOTIMPL
| WindowsIsStringEmpty | 不存在时,返回 E_NOTIMPL
| WindowsStringHasEmbeddedNull | 不存在时,返回 E_NOTIMPL
| WindowsCompareStringOrdinal | 不存在时,返回 E_NOTIMPL
| WindowsCreateString | 不存在时,内部实现
| WindowsCreateStringReference | 不存在时,内部实现
| WindowsDeleteString | 不存在时,内部实现
| WindowsDuplicateString | 不存在时,内部实现
| WindowsGetStringLen | 不存在时,内部实现
| WindowsGetStringRawBuffer | 不存在时,内部实现
| WindowsIsStringEmpty | 不存在时,内部实现
| WindowsStringHasEmbeddedNull | 不存在时,内部实现
| WindowsCompareStringOrdinal | 不存在时,内部实现

## advapi32.dll
| 函数 | Fallback
Expand Down
221 changes: 205 additions & 16 deletions src/Thunks/api-ms-win-core-winrt-string.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <winstring.h>
#include <hstring_private.h>
#include <winstring.h>

namespace YY
{
Expand All @@ -25,10 +26,43 @@ namespace YY
return pWindowsCreateString(sourceString, length, string);
}

if (string)
*string = nullptr;
if (!string)
{
return E_INVALIDARG;
}
*string = nullptr;

if (!sourceString && 0 != length)
{
return E_POINTER;
}

SIZE_T RequiredSize = sizeof(STRING_OPAQUE) + length * sizeof(WCHAR);
if (MAXUINT32 < RequiredSize)
{
return MEM_E_INVALID_SIZE;
}

return E_NOTIMPL;
PSTRING_OPAQUE Result =
reinterpret_cast<PSTRING_OPAQUE>(::HeapAlloc(
::GetProcessHeap(),
HEAP_ZERO_MEMORY,
RequiredSize));
if (!Result)
{
return E_OUTOFMEMORY;
}

Result->Header.Flags = WRHF_NONE;
Result->Header.Length = length;
Result->Header.StringRef = Result->String;
Result->RefCount = 1;
::memcpy(Result->String, sourceString, length * sizeof(WCHAR));
Result->String[length] = L'\0';

*string = reinterpret_cast<HSTRING>(Result);

return S_OK;
}
#endif

Expand All @@ -54,10 +88,36 @@ namespace YY
return pWindowsCreateStringReference(sourceString, length, hstringHeader, string);
}

if (string)
*string = nullptr;
if (!string || !hstringHeader)
{
return E_INVALIDARG;
}
*string = nullptr;

return E_NOTIMPL;
if (!sourceString && 0 != length)
{
return E_POINTER;
}

if (sourceString)
{
if (L'0' != sourceString[length])
{
return E_STRING_NOT_NULL_TERMINATED;
}
}

HSTRING_HEADER_INTERNAL* Header =
reinterpret_cast<HSTRING_HEADER_INTERNAL*>(hstringHeader);
::memset(Header, 0, sizeof(HSTRING_HEADER_INTERNAL));

Header->Flags = WRHF_STRING_REFERENCE;
Header->Length = length;
Header->StringRef = sourceString;

*string = reinterpret_cast<HSTRING>(Header);

return S_OK;
}
#endif

Expand All @@ -80,7 +140,21 @@ namespace YY
return pWindowsDeleteString(string);
}

return E_NOTIMPL;
if (string)
{
STRING_OPAQUE* OpaqueString =
reinterpret_cast<STRING_OPAQUE*>(string);
if (!(OpaqueString->Header.Flags & WRHF_STRING_REFERENCE))
{
if (0 == ::InterlockedDecrement(
reinterpret_cast<LONG volatile*>(&OpaqueString->RefCount)))
{
::HeapFree(::GetProcessHeap(), 0, OpaqueString);
}
}
}

return S_OK;
}
#endif

Expand All @@ -104,11 +178,30 @@ namespace YY
return pWindowsDuplicateString(string, newString);
}

if (!newString)
{
return E_INVALIDARG;
}
*newString = nullptr;

if (newString)
*newString = nullptr;
if (string)
{
STRING_OPAQUE* OpaqueString =
reinterpret_cast<STRING_OPAQUE*>(string);
if (OpaqueString->Header.Flags & WRHF_STRING_REFERENCE)
{
return ::WindowsCreateString(
OpaqueString->Header.StringRef,
OpaqueString->Header.Length,
newString);
}

::InterlockedIncrement(
reinterpret_cast<LONG volatile*>(&OpaqueString->RefCount));
*newString = string;
}

return E_NOTIMPL;
return S_OK;
}
#endif

Expand All @@ -131,6 +224,13 @@ namespace YY
return pWindowsGetStringLen(string);
}

if (string)
{
STRING_OPAQUE* OpaqueString =
reinterpret_cast<STRING_OPAQUE*>(string);
return OpaqueString->Header.Length;
}

return 0;
}
#endif
Expand All @@ -155,10 +255,24 @@ namespace YY
return pWindowsGetStringRawBuffer(string, length);
}

if (!string)
{
if (length)
{
*length = 0;
}

return L"\0";
}

STRING_OPAQUE* OpaqueString =
reinterpret_cast<STRING_OPAQUE*>(string);
if (length)
*length = 0;
{
*length = OpaqueString->Header.Length;
}

return nullptr;
return OpaqueString->Header.StringRef;
}
#endif

Expand All @@ -181,6 +295,13 @@ namespace YY
return pWindowsIsStringEmpty(string);
}

if (string)
{
STRING_OPAQUE* OpaqueString =
reinterpret_cast<STRING_OPAQUE*>(string);
return 0 == OpaqueString->Header.Length;
}

return TRUE;
}
#endif
Expand All @@ -205,7 +326,28 @@ namespace YY
return pWindowsStringHasEmbeddedNull(string, hasEmbedNull);
}

return E_NOTIMPL;
if (!hasEmbedNull)
{
return E_INVALIDARG;
}
*hasEmbedNull = FALSE;

if (string)
{
STRING_OPAQUE* OpaqueString =
reinterpret_cast<STRING_OPAQUE*>(string);
if (!(OpaqueString->Header.Flags & WRHF_EMBEDDED_NULLS_COMPUTED))
{
OpaqueString->Header.Flags |= WRHF_EMBEDDED_NULLS_COMPUTED;
OpaqueString->Header.Flags |=
(nullptr != ::wcschr(
OpaqueString->Header.StringRef,
L'\0')) ? WRHF_HAS_EMBEDDED_NULLS : WRHF_NONE;
}
*hasEmbedNull = OpaqueString->Header.Flags & WRHF_HAS_EMBEDDED_NULLS;
}

return S_OK;
}
#endif

Expand All @@ -230,9 +372,56 @@ namespace YY
return pWindowsCompareStringOrdinal(string1, string2, result);
}

return E_NOTIMPL;
if (!result)
{
return E_INVALIDARG;
}
*result = 0;

if (string1 && string2)
{
STRING_OPAQUE* OpaqueString1 =
reinterpret_cast<STRING_OPAQUE*>(string1);
STRING_OPAQUE* OpaqueString2 =
reinterpret_cast<STRING_OPAQUE*>(string2);

int CompareResult = ::CompareStringOrdinal(
OpaqueString1->Header.StringRef,
OpaqueString1->Header.Length,
OpaqueString2->Header.StringRef,
OpaqueString2->Header.Length,
FALSE);
if (CompareResult == CSTR_LESS_THAN)
{
*result = -1;
}
else if (CompareResult == CSTR_GREATER_THAN)
{
*result = 1;
}
}
else if (string1 && !string2)
{
STRING_OPAQUE* OpaqueString1 =
reinterpret_cast<STRING_OPAQUE*>(string1);
if (OpaqueString1->Header.Length)
{
*result = 1;
}
}
else if (!string1 && string2)
{
STRING_OPAQUE* OpaqueString2 =
reinterpret_cast<STRING_OPAQUE*>(string2);
if (OpaqueString2->Header.Length)
{
*result = 1;
}
}

return S_OK;
}
#endif

}
}
}

0 comments on commit 9a97c4b

Please sign in to comment.