Merge from amd64-branch:
[reactos.git] / reactos / dll / win32 / user32 / misc / resources.c
1 #include <user32.h>
2
3 #include <wine/debug.h>
4
5 #ifndef _CFGMGR32_H_
6 #define CR_SUCCESS 0x00000000
7 #define CR_OUT_OF_MEMORY 0x00000002
8 #define CR_INVALID_POINTER 0x00000003
9 #define CR_INVALID_DATA 0x0000001F
10 #endif
11
12 typedef DWORD (WINAPI *CMP_REGNOTIFY) (HANDLE, LPVOID, DWORD, PULONG);
13 typedef DWORD (WINAPI *CMP_UNREGNOTIFY) (ULONG );
14
15 /* FIXME: Currently IsBadWritePtr is implemented using VirtualQuery which
16 does not seem to work properly for stack address space. */
17 /* kill `left-hand operand of comma expression has no effect' warning */
18 #define IsBadWritePtr(lp, n) ((DWORD)lp==n?0:0)
19
20
21 static HINSTANCE hSetupApi = NULL;
22
23
24 /*
25 * @implemented (Synced with Wine 08.01.2009)
26 */
27 INT
28 WINAPI
29 LoadStringA(HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen)
30 {
31 HGLOBAL hmem;
32 HRSRC hrsrc;
33 DWORD retval = 0;
34
35 if (!buflen) return -1;
36
37 /* Use loword (incremented by 1) as resourceid */
38 if ((hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1),
39 (LPWSTR)RT_STRING )) &&
40 (hmem = LoadResource( instance, hrsrc )))
41 {
42 const WCHAR *p = LockResource(hmem);
43 unsigned int id = resource_id & 0x000f;
44
45 while (id--) p += *p + 1;
46
47 RtlUnicodeToMultiByteN( buffer, buflen - 1, &retval, (PWSTR)(p + 1), *p * sizeof(WCHAR) );
48 }
49 buffer[retval] = 0;
50 return retval;
51 }
52
53
54 /*
55 * @implemented (Synced with Wine 08.01.2009)
56 */
57 INT
58 WINAPI
59 LoadStringW(HINSTANCE instance, UINT resource_id, LPWSTR buffer, INT buflen)
60 {
61 HGLOBAL hmem;
62 HRSRC hrsrc;
63 WCHAR *p;
64 int string_num;
65 int i;
66
67 if(buffer == NULL)
68 return 0;
69
70 /* Use loword (incremented by 1) as resourceid */
71 hrsrc = FindResourceW( instance, MAKEINTRESOURCEW((LOWORD(resource_id) >> 4) + 1),
72 (LPWSTR)RT_STRING );
73 if (!hrsrc) return 0;
74 hmem = LoadResource( instance, hrsrc );
75 if (!hmem) return 0;
76
77 p = LockResource(hmem);
78 string_num = resource_id & 0x000f;
79 for (i = 0; i < string_num; i++)
80 p += *p + 1;
81
82 /*if buflen == 0, then return a read-only pointer to the resource itself in buffer
83 it is assumed that buffer is actually a (LPWSTR *) */
84 if(buflen == 0)
85 {
86 *((LPWSTR *)buffer) = p + 1;
87 return *p;
88 }
89
90 i = min(buflen - 1, *p);
91 if (i > 0) {
92 memcpy(buffer, p + 1, i * sizeof (WCHAR));
93 buffer[i] = 0;
94 } else {
95 if (buflen > 1) {
96 buffer[0] = 0;
97 return 0;
98 }
99 }
100
101 return i;
102 }
103
104
105 /*
106 * @implemented
107 */
108 HDEVNOTIFY
109 WINAPI
110 RegisterDeviceNotificationW(HANDLE hRecipient,
111 LPVOID NotificationFilter,
112 DWORD Flags)
113 {
114 DWORD ConfigRet = 0;
115 CMP_REGNOTIFY RegNotify = NULL;
116 HDEVNOTIFY hDevNotify = NULL;
117
118 if (hSetupApi == NULL) hSetupApi = LoadLibraryA("SETUPAPI.DLL");
119 if (hSetupApi == NULL) return NULL;
120
121 RegNotify = (CMP_REGNOTIFY) GetProcAddress(hSetupApi, "CMP_RegisterNotification");
122 if (RegNotify == NULL)
123 {
124 FreeLibrary(hSetupApi);
125 hSetupApi = NULL;
126 return NULL;
127 }
128
129 ConfigRet = RegNotify(hRecipient, NotificationFilter, Flags, (PULONG) &hDevNotify);
130 if (ConfigRet != CR_SUCCESS)
131 {
132 switch (ConfigRet)
133 {
134 case CR_OUT_OF_MEMORY:
135 SetLastError (ERROR_NOT_ENOUGH_MEMORY);
136 break;
137
138 case CR_INVALID_POINTER:
139 SetLastError (ERROR_INVALID_PARAMETER);
140 break;
141
142 case CR_INVALID_DATA:
143 SetLastError (ERROR_INVALID_DATA);
144 break;
145
146 default:
147 SetLastError (ERROR_SERVICE_SPECIFIC_ERROR);
148 break;
149 }
150 }
151
152 return hDevNotify;
153 }
154
155
156 /*
157 * @implemented
158 */
159 BOOL
160 WINAPI
161 UnregisterDeviceNotification(HDEVNOTIFY Handle)
162 {
163 DWORD ConfigRet = 0;
164 CMP_UNREGNOTIFY UnRegNotify = NULL;
165
166 if (hSetupApi == NULL) hSetupApi = LoadLibraryA("SETUPAPI.DLL");
167 if (hSetupApi == NULL) return FALSE;
168
169 UnRegNotify = (CMP_UNREGNOTIFY) GetProcAddress(hSetupApi, "CMP_UnregisterNotification");
170 if (UnRegNotify == NULL)
171 {
172 FreeLibrary(hSetupApi);
173 hSetupApi = NULL;
174 return FALSE;
175 }
176
177 ConfigRet = UnRegNotify((ULONG) Handle );
178 if (ConfigRet != CR_SUCCESS)
179 {
180 switch (ConfigRet)
181 {
182 case CR_INVALID_POINTER:
183 SetLastError (ERROR_INVALID_PARAMETER);
184 break;
185
186 case CR_INVALID_DATA:
187 SetLastError (ERROR_INVALID_DATA);
188 break;
189
190 default:
191 SetLastError (ERROR_SERVICE_SPECIFIC_ERROR);
192 break;
193 }
194 return FALSE;
195 }
196
197 return TRUE;
198 }
199
200 /* EOF */