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