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