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