1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | #include <stdio.h> |
7 | #include <utilcode.h> |
8 | #include "resourcestring.h" |
9 | |
10 | static int CompareNativeStringResources(const void *a, const void *b) |
11 | { |
12 | unsigned int resourceIdA = ((NativeStringResource*)a)->resourceId; |
13 | unsigned int resourceIdB = ((NativeStringResource*)b)->resourceId; |
14 | |
15 | if (resourceIdA < resourceIdB) |
16 | return -1; |
17 | |
18 | if (resourceIdA == resourceIdB) |
19 | return 0; |
20 | |
21 | return 1; |
22 | } |
23 | |
24 | int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResourceTable, unsigned int iResourceID, WCHAR* szBuffer, int iMax, int *pcwchUsed) |
25 | { |
26 | int len = 0; |
27 | if (szBuffer && iMax) |
28 | { |
29 | // Search the sorted set of resources for the ID we're interested in. |
30 | NativeStringResource searchEntry = {iResourceID, NULL}; |
31 | NativeStringResource *resourceEntry = (NativeStringResource*)bsearch( |
32 | &searchEntry, |
33 | nativeStringResourceTable.table, |
34 | nativeStringResourceTable.size, |
35 | sizeof(NativeStringResource), |
36 | CompareNativeStringResources); |
37 | |
38 | if (resourceEntry != NULL) |
39 | { |
40 | len = PAL_GetResourceString(NULL, resourceEntry->resourceString, szBuffer, iMax); |
41 | if (len == 0) |
42 | { |
43 | int hr = HRESULT_FROM_GetLastError(); |
44 | |
45 | // Tell the caller if the buffer isn't big enough |
46 | if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) && pcwchUsed) |
47 | *pcwchUsed = iMax; |
48 | |
49 | return hr; |
50 | } |
51 | } |
52 | else |
53 | { |
54 | // The resource ID wasn't found in our array. Fall back on returning the ID as a string. |
55 | len = _snwprintf_s(szBuffer, iMax, _TRUNCATE, W("[Undefined resource string ID:0x%X]" ), iResourceID); |
56 | if (len < 0) |
57 | { |
58 | // The only possible failure is that that string didn't fit the buffer. So the buffer contains |
59 | // partial string terminated by '\0' |
60 | // We could return ERROR_INSUFFICIENT_BUFFER, but we'll error on the side of caution here and |
61 | // actually show something (given that this is likely a scenario involving a bug/deployment issue) |
62 | len = iMax - 1; |
63 | } |
64 | } |
65 | } |
66 | |
67 | if (pcwchUsed) |
68 | { |
69 | *pcwchUsed = len; |
70 | } |
71 | |
72 | return S_OK; |
73 | } |
74 | |
75 | |