Release 950302
[wine] / loader / resource.c
1 /*
2 static char RCSId[] = "$Id: resource.c,v 1.4 1993/07/04 04:04:21 root Exp root $";
3 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
4 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include "arch.h"
13 #include "windows.h"
14 #include "gdi.h"
15 #include "bitmap.h"
16 #include "neexe.h"
17 #include "icon.h"
18 #include "menu.h"
19 #include "accel.h"
20 #include "dlls.h"
21 #include "resource.h"
22 #include "library.h"
23 #include "stddebug.h"
24 #include "debug.h"
25
26 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
27
28 RESOURCE *Top = NULL;
29
30 extern int NE_FindResource(HANDLE, LPSTR, LPSTR, RESOURCE *);
31 extern int PE_FindResource(HANDLE, LPSTR, LPSTR, RESOURCE *);
32
33 #define PrintId(name) \
34         if (HIWORD((DWORD)name)) \
35                 printf(", %s", name); \
36         else \
37                 printf(", #%d", (int) name); 
38
39 /**********************************************************************
40  *                      FindResource    [KERNEL.60]
41  */
42 HANDLE FindResource(HANDLE instance, LPSTR name, LPSTR type)
43 {
44         int status;
45         RESOURCE *r;
46         HANDLE rh;
47
48         if(debugging_resource){
49         printf("FindResource(%04X", instance);
50         PrintId(name);
51         PrintId(type);
52         printf(")\n");
53         }
54         
55         /* FIXME: did we already find this one ? */
56
57         if ((rh = GlobalAlloc(GMEM_MOVEABLE, sizeof(RESOURCE))) == 0)
58                 return 0;
59
60         r = (RESOURCE *)GlobalLock(rh);
61         r->next = Top;
62         Top = r;
63         r->info_mem = rh;
64         r->rsc_mem = 0;
65         r->count = 0;
66         if (HIWORD((DWORD)name))
67                 r->name = strdup(name);
68         else
69                 r->name = name;
70
71         if (HIWORD((DWORD)type))
72                 r->type = strdup(type);
73         else
74                 r->type = type;
75
76         r->wpnt = GetFileInfo(instance);
77         r->fd = dup(r->wpnt->fd);
78         if (r->wpnt->ne)
79                 status = NE_FindResource(instance, name, type, r);
80         else
81                 status = PE_FindResource(instance, name, type, r);
82
83         if (!status) {
84                 if (HIWORD((DWORD)r->name))
85                         free(r->name);
86
87                 if (HIWORD((DWORD)r->type))
88                         free(r->type);
89                 close(r->fd);
90
91                 Top = r->next;
92                 GlobalUnlock(rh);
93                 return 0;
94         } else
95                 return rh;
96 }
97
98 /**********************************************************************
99  *                      AllocResource   [KERNEL.66]
100  */
101 HANDLE AllocResource(HANDLE instance, HANDLE hResInfo, DWORD dwSize)
102 {
103         RESOURCE *r;
104         int image_size;
105
106         dprintf_resource(stddeb, "AllocResource(%04X, %04X, %08X);\n", 
107                 instance, hResInfo, (int) dwSize);
108
109         if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
110                 return 0;
111     
112         image_size = r->size;
113
114         if (dwSize == 0)
115                 r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, image_size);
116         else
117                 r->rsc_mem = GlobalAlloc(GMEM_MOVEABLE, dwSize);
118
119         GlobalUnlock(hResInfo);
120
121         return r->rsc_mem;
122 }
123 \f
124 /**********************************************************************
125  *                              AccessResource  [KERNEL.64]
126  */
127 int AccessResource(HANDLE instance, HANDLE hResInfo)
128 {
129         int fd;
130         RESOURCE *r;
131
132         dprintf_resource(stddeb, "AccessResource(%04X, %04X);\n", 
133                 instance, hResInfo);
134
135         if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
136                 return -1;
137
138         fd = r->fd;
139         lseek(fd, r->offset, SEEK_SET);
140         GlobalUnlock(hResInfo);
141
142         return fd;
143 }
144 \f
145 /**********************************************************************
146  *                              SizeofResource  [KERNEL.65]
147  */
148 WORD SizeofResource(HANDLE instance, HANDLE hResInfo)
149 {
150         RESOURCE *r;
151         int size;
152         
153         dprintf_resource(stddeb, "SizeofResource(%04X, %04X);\n", 
154                 instance, hResInfo);
155
156         if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
157                 return 0;
158
159         size = r->size;
160         GlobalUnlock(hResInfo);
161
162         return size;
163 }
164
165 /**********************************************************************
166  *                      LoadResource    [KERNEL.61]
167  */
168 HANDLE LoadResource(HANDLE instance, HANDLE hResInfo)
169 {
170     RESOURCE *r;
171     int image_size, fd;
172     void *image;
173     HANDLE h;
174
175     dprintf_resource(stddeb, "LoadResource(%04X, %04X);\n", instance, hResInfo);
176
177     if ((r = (RESOURCE *)GlobalLock(hResInfo)) == NULL)
178         return 0;
179     
180     h = r->rsc_mem = AllocResource(instance, hResInfo, 0);
181     image = GlobalLinearLock(h);
182     image_size = r->size;
183     fd = AccessResource(instance, hResInfo);
184
185     if (image == NULL || read(fd, image, image_size) != image_size) {
186         GlobalFree(h);
187         GlobalUnlock(hResInfo);
188         return 0;
189     }
190     r->count++;
191     close(fd);
192     GlobalLinearUnlock(h);
193     GlobalUnlock(hResInfo);
194     return h;
195 }
196
197 /**********************************************************************
198  *                              LockResource    [KERNEL.62]
199  */
200 LPSTR LockResource(HANDLE hResData)
201 {
202     return GlobalLock(hResData);
203 }
204
205 /**********************************************************************
206  *                              FreeResource    [KERNEL.63]
207  */
208 HANDLE FreeResource(HANDLE hResData)
209 {
210     RESOURCE *r, *rp;
211
212     dprintf_resource(stddeb, "FreeResource: handle %04x\n", hResData);
213
214     for (r = rp = Top; r ; r = r->next) {
215         if (r->rsc_mem == hResData) {
216             if (r->count == 0) {
217                     if (rp != r)
218                         rp->next = r->next;
219                     else
220                         Top = r->next;
221
222                     if (HIWORD((DWORD)r->name))
223                         free(r->name);
224                     if (HIWORD((DWORD)r->type))
225                         free(r->type);
226                     GlobalFree(r->rsc_mem);
227                     GlobalFree(r->info_mem);
228                     return 0;
229             } else
230                 r->count--;
231         }
232         rp = r;
233     }
234     return hResData;
235 }
236 \f
237 /**********************************************************************
238  *                      ConvertCoreBitmap
239  */
240 HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image )
241 {
242     BITMAPINFO * bmpInfo;
243     HBITMAP hbitmap;
244     char * bits;
245     int i, size, n_colors;
246    
247     n_colors = 1 << image->bcBitCount;
248     if (image->bcBitCount < 24)
249     {
250         size = sizeof(BITMAPINFOHEADER) + n_colors * sizeof(RGBQUAD);   
251         bits = (char *) (image + 1) + (n_colors * sizeof(RGBTRIPLE));
252     }
253     else
254     {
255         size = sizeof(BITMAPINFOHEADER);
256         bits = (char *) (image + 1);
257     }
258     bmpInfo = (BITMAPINFO *) malloc( size );
259
260     bmpInfo->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
261     bmpInfo->bmiHeader.biWidth         = image->bcWidth;
262     bmpInfo->bmiHeader.biHeight        = image->bcHeight;
263     bmpInfo->bmiHeader.biPlanes        = image->bcPlanes;
264     bmpInfo->bmiHeader.biBitCount      = image->bcBitCount;
265     bmpInfo->bmiHeader.biCompression   = 0;
266     bmpInfo->bmiHeader.biSizeImage     = 0;
267     bmpInfo->bmiHeader.biXPelsPerMeter = 0;
268     bmpInfo->bmiHeader.biYPelsPerMeter = 0;
269     bmpInfo->bmiHeader.biClrUsed       = 0;
270     bmpInfo->bmiHeader.biClrImportant  = 0;
271
272     if (image->bcBitCount < 24)
273     {
274         RGBTRIPLE * oldMap = (RGBTRIPLE *)(image + 1);
275         RGBQUAD * newMap = bmpInfo->bmiColors;
276         for (i = 0; i < n_colors; i++, oldMap++, newMap++)
277         {
278             newMap->rgbRed      = oldMap->rgbtRed;
279             newMap->rgbGreen    = oldMap->rgbtGreen;
280             newMap->rgbBlue     = oldMap->rgbtBlue;
281             newMap->rgbReserved = 0;
282         }
283     }
284
285     hbitmap = CreateDIBitmap( hdc, &bmpInfo->bmiHeader, CBM_INIT,
286                               bits, bmpInfo, DIB_RGB_COLORS );
287     free( bmpInfo );
288     return hbitmap;
289 }
290
291 /**********************************************************************
292  *                      ConvertInfoBitmap
293  */
294 HBITMAP ConvertInfoBitmap( HDC hdc, BITMAPINFO * image )
295 {
296     char * bits = ((char *)image) + DIB_BitmapInfoSize(image, DIB_RGB_COLORS);
297     return CreateDIBitmap( hdc, &image->bmiHeader, CBM_INIT,
298                            bits, image, DIB_RGB_COLORS );
299
300
301 /**********************************************************************
302  *                      RSC_LoadResource
303  */
304 HANDLE
305 RSC_LoadResource(int instance, LPSTR rsc_name, LPSTR type, int *image_size_ret)
306 {
307         HANDLE hResInfo;
308         RESOURCE *r;
309
310         dprintf_resource(stddeb, "RSC_LoadResource: instance = %04x, name = %08x, type = %08x\n",
311            instance, (int) rsc_name, (int) type);
312
313         if ((hResInfo = FindResource(instance, rsc_name, (LPSTR) type)) == (HANDLE) NULL) {
314                 return (HANDLE)NULL;
315         }
316         r = (RESOURCE *)GlobalLock(hResInfo);
317         if (image_size_ret) 
318                 *image_size_ret = r->size;
319         r->count++;
320         GlobalUnlock(hResInfo);
321         return LoadResource(instance, hResInfo);
322 }
323 \f
324 /**********************************************************************
325  *                      LoadIcon [USER.174]
326  */
327 HICON LoadIcon(HANDLE instance, LPSTR icon_name)
328 {
329     HICON       hIcon;
330     HANDLE      rsc_mem;
331     WORD        *lp;
332     ICONDESCRIP *lpicodesc;
333     ICONALLOC   *lpico;
334     int         width, height;
335     BITMAPINFO  *bmi;
336     BITMAPINFOHEADER    *bih;
337     RGBQUAD     *rgbq;
338     HDC         hdc;
339     int         image_size;
340
341     if(debugging_resource){
342         printf("LoadIcon(%04X", instance);
343         PrintId(icon_name);
344         printf(")\n");
345     }
346     
347     if (!instance)
348     {
349         if (HIWORD((int)icon_name)) return 0; /* FIXME: should handle '#xxx' */
350         return OBM_LoadIcon( LOWORD((int)icon_name) );
351     }
352
353     if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
354     rsc_mem = RSC_LoadResource(instance, icon_name, (LPSTR) NE_RSCTYPE_GROUP_ICON, 
355                                &image_size);
356     if (rsc_mem == (HANDLE)NULL) {
357         printf("LoadIcon / Icon %04X not Found !\n", (int) icon_name);
358         ReleaseDC(GetDesktopWindow(), hdc); 
359         return 0;
360         }
361     lp = (WORD *)GlobalLock(rsc_mem);
362     if (lp == NULL) {
363         GlobalFree(rsc_mem);
364         ReleaseDC(GetDesktopWindow(), hdc); 
365         return 0;
366         }
367     lpicodesc = (ICONDESCRIP *)(lp + 3);
368     hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
369     if (hIcon == (HICON)NULL) {
370         GlobalFree(rsc_mem);
371         ReleaseDC(GetDesktopWindow(), hdc); 
372         return 0;
373         }
374     lpico = (ICONALLOC *)GlobalLock(hIcon);
375     lpico->descriptor = *lpicodesc;
376     width = lpicodesc->Width;
377     height = lpicodesc->Height;
378     GlobalUnlock(rsc_mem);
379     GlobalFree(rsc_mem);
380     rsc_mem = RSC_LoadResource(instance, 
381         MAKEINTRESOURCE(lpicodesc->icoDIBOffset), 
382         (LPSTR) NE_RSCTYPE_ICON, &image_size);
383     if (rsc_mem == (HANDLE)NULL) {
384         printf("LoadIcon / Icon %04X Bitmaps not Found !\n", (int) icon_name);
385         ReleaseDC(GetDesktopWindow(), hdc); 
386         return 0;
387         }
388     lp = (WORD *)GlobalLock(rsc_mem);
389     if (lp == NULL) {
390         GlobalFree(rsc_mem);
391         ReleaseDC(GetDesktopWindow(), hdc); 
392         return 0;
393         }
394     bmi = (BITMAPINFO *)lp;
395     bih = (BITMAPINFOHEADER *)lp;
396     rgbq = &bmi->bmiColors[0];
397     bih->biHeight = bih->biHeight / 2;
398 /*
399     printf("LoadIcon / image_size=%d width=%d height=%d bih->biBitCount=%d bih->biSizeImage=%ld\n", 
400         image_size, width, height, bih->biBitCount, bih->biSizeImage);
401 */
402     if (bih->biSize == sizeof(BITMAPINFOHEADER))
403         lpico->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)bih);
404     else
405         lpico->hBitmap = 0;
406     bih->biBitCount = 1;
407     bih->biClrUsed = bih->biClrImportant  = 2;
408     rgbq[0].rgbBlue = rgbq[0].rgbGreen = rgbq[0].rgbRed = 0x00;
409     rgbq[1].rgbBlue = rgbq[1].rgbGreen = rgbq[1].rgbRed = 0xff;
410     rgbq[0].rgbReserved = rgbq[1].rgbReserved = 0;
411     if (bih->biSizeImage == 0) {
412         if (bih->biCompression != BI_RGB) {
413             fprintf(stderr,"Unknown size for compressed Icon bitmap.\n");
414             GlobalFree(rsc_mem);
415             ReleaseDC(GetDesktopWindow(), hdc); 
416             return 0;
417             }
418         bih->biSizeImage = (bih->biWidth * bih->biHeight * bih->biBitCount
419                             + 7) / 8;
420         }
421     lpico->hBitMask = CreateDIBitmap(hdc, bih, CBM_INIT,
422         (LPSTR)lp + bih->biSizeImage - sizeof(BITMAPINFOHEADER) / 2 - 4,
423         (BITMAPINFO *)bih, DIB_RGB_COLORS );
424     GlobalUnlock(rsc_mem);
425     GlobalFree(rsc_mem);
426     ReleaseDC(GetDesktopWindow(), hdc);
427     GlobalUnlock(hIcon);
428     dprintf_resource(stddeb,"LoadIcon Alloc hIcon=%X\n", hIcon);
429     return hIcon;
430 }
431 \f
432 /**********************************************************************
433  *                      CreateIcon [USER.407]
434  */
435 HICON CreateIcon(HANDLE hInstance, int nWidth, int nHeight, 
436                  BYTE nPlanes, BYTE nBitsPixel, LPSTR lpANDbits, 
437                  LPSTR lpXORbits)
438 {
439     HICON       hIcon;
440     ICONALLOC   *lpico;
441
442     dprintf_resource(stddeb, "CreateIcon: hInstance = %04x, nWidth = %08x, nHeight = %08x \n",
443             hInstance, nWidth, nHeight);
444     dprintf_resource(stddeb, "  nPlanes = %04x, nBitsPixel = %04x,",nPlanes, nBitsPixel);
445     dprintf_resource(stddeb, " lpANDbits= %04x, lpXORbits = %04x, \n", (int)lpANDbits,
446                 (int)lpXORbits);
447
448     if (hInstance == (HANDLE)NULL) { 
449         printf("CreateIcon / hInstance %04x not Found!\n",hInstance);
450         return 0;
451         }
452     hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
453     if (hIcon == (HICON)NULL) {
454         printf("Can't allocate memory for Icon in CreateIcon\n");
455         return 0;
456         }
457     lpico= (ICONALLOC *)GlobalLock(hIcon);
458
459     lpico->descriptor.Width=nWidth;
460     lpico->descriptor.Height=nHeight;
461     lpico->descriptor.ColorCount=16; /* Dummy Value */ 
462     lpico->descriptor.Reserved1=0;
463     lpico->descriptor.Reserved2=nPlanes;
464     lpico->descriptor.Reserved3=nWidth*nHeight;
465
466     /* either nPlanes and/or nBitCount is set to one */
467     lpico->descriptor.icoDIBSize=nWidth*nHeight*nPlanes*nBitsPixel; 
468     lpico->descriptor.icoDIBOffset=0; 
469
470     if( !(lpico->hBitmap=CreateBitmap(nWidth, nHeight, nPlanes, nBitsPixel, 
471                                  lpXORbits)) ) {
472       printf("CreateIcon: couldn't create the XOR bitmap\n");
473       return(0);
474     }
475     
476     /* the AND BitMask is always monochrome */
477     if( !(lpico->hBitMask=CreateBitmap(nWidth, nHeight, 1, 1, lpANDbits)) ) {
478       printf("CreateIcon: couldn't create the AND bitmap\n");
479       return(0);
480     }
481
482     GlobalUnlock(hIcon);
483     dprintf_resource(stddeb, "CreateIcon Alloc hIcon=%X\n", hIcon);
484     return hIcon;
485 }
486 \f
487 /**********************************************************************
488  *                      DestroyIcon [USER.457]
489  */
490 BOOL DestroyIcon(HICON hIcon)
491 {
492     ICONALLOC   *lpico;
493     
494     if (hIcon == (HICON)NULL)
495         return FALSE;
496     lpico = (ICONALLOC *)GlobalLock(hIcon);
497     if (lpico->hBitmap != (HBITMAP)NULL) 
498         DeleteObject(lpico->hBitmap);
499     GlobalFree(hIcon);
500     return TRUE;
501 }
502 \f
503 /**********************************************************************
504  *                      LoadAccelerators        [USER.177]
505  */
506 HANDLE LoadAccelerators(HANDLE instance, LPSTR lpTableName)
507 {
508     HANDLE      hAccel;
509     HANDLE      rsc_mem;
510     BYTE        *lp;
511     ACCELHEADER *lpAccelTbl;
512     int         i, image_size, n;
513
514     if(debugging_accel){
515         printf("LoadAccelerators(%04X", instance);
516         PrintId(lpTableName);
517         printf(")\n");
518     }
519
520     rsc_mem = RSC_LoadResource(instance, lpTableName, (LPSTR) NE_RSCTYPE_ACCELERATOR, 
521                                &image_size);
522     if (rsc_mem == (HANDLE)NULL) {
523         printf("LoadAccelerators(%04X", instance);
524         PrintId(lpTableName);
525         printf(") not found !\n");
526         return 0;
527         }
528     lp = (BYTE *)GlobalLock(rsc_mem);
529     if (lp == NULL) {
530         GlobalFree(rsc_mem);
531         return 0;
532         }
533     dprintf_accel(stddeb,"LoadAccelerators / image_size=%d\n", image_size);
534     n = image_size/5;
535     hAccel = GlobalAlloc(GMEM_MOVEABLE, 
536         sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY));
537     lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
538     lpAccelTbl->wCount = 0;
539     for (i = 0; i < n; i++) {
540         lpAccelTbl->tbl[i].type = *(lp++);
541         lpAccelTbl->tbl[i].wEvent = *((WORD *)lp);
542         lp += 2;
543         lpAccelTbl->tbl[i].wIDval = *((WORD *)lp);
544         lp += 2;
545         if (lpAccelTbl->tbl[i].wEvent == 0) break;
546         dprintf_accel(stddeb,
547                 "Accelerator #%u / event=%04X id=%04X type=%02X \n", 
548                 i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval, 
549                 lpAccelTbl->tbl[i].type);
550         lpAccelTbl->wCount++;
551         }
552     GlobalUnlock(hAccel);
553     GlobalUnlock(rsc_mem);
554     GlobalFree(rsc_mem);
555     return hAccel;
556 }
557 \f
558 /**********************************************************************
559  *                      TranslateAccelerator    [USER.178]
560  */
561 int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg)
562 {
563     ACCELHEADER *lpAccelTbl;
564     int         i;
565     
566     if (hAccel == 0 || msg == NULL) return 0;
567     if (msg->message != WM_KEYDOWN &&
568         msg->message != WM_KEYUP &&
569         msg->message != WM_CHAR) return 0;
570
571     dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04X !\n", hAccel);
572
573     lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel);
574     for (i = 0; i < lpAccelTbl->wCount; i++) {
575         if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) {
576             if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
577                 msg->message == WM_KEYDOWN) {
578                 if ((lpAccelTbl->tbl[i].type & SHIFT_ACCEL) &&
579                     !(GetKeyState(VK_SHIFT) & 0xf)) {
580                     GlobalUnlock(hAccel);
581                     return 0;
582                 }
583                 if ((lpAccelTbl->tbl[i].type & CONTROL_ACCEL) &&
584                     !(GetKeyState(VK_CONTROL) & 0xf)) {
585                     GlobalUnlock(hAccel);
586                     return 0;
587                 }
588                 if ((lpAccelTbl->tbl[i].type & ALT_ACCEL) &&
589                     !(GetKeyState(VK_MENU) & 0xf)) {
590                     GlobalUnlock(hAccel);
591                     return 0;
592                 }
593                 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
594                 GlobalUnlock(hAccel);
595                 return 1;
596                 }
597             if (msg->message == WM_KEYUP) return 1;
598             }
599         else {
600             if (msg->wParam == lpAccelTbl->tbl[i].wEvent &&
601                 msg->message == WM_CHAR) {
602                 SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L);
603                 GlobalUnlock(hAccel);
604                 return 1;
605                 }
606             }
607         }
608     GlobalUnlock(hAccel);
609     return 0;
610 }
611 \f
612 /**********************************************************************
613  *                                      LoadString
614  */
615 int
616 LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen)
617 {
618     HANDLE hmem;
619     int rsc_size;
620     unsigned char *p;
621     int string_num;
622     int i;
623
624     dprintf_resource(stddeb, "LoadString: instance = %04x, id = %d, buffer = %08x, "
625            "length = %d\n", instance, resource_id, (int) buffer, buflen);
626
627     hmem = RSC_LoadResource(instance, (char *) ((resource_id >> 4) + 1),
628                             (LPSTR) NE_RSCTYPE_STRING, &rsc_size);
629     if (hmem == 0)
630         return 0;
631     
632     p = GlobalLock(hmem);
633     string_num = resource_id & 0x000f;
634     for (i = 0; i < string_num; i++)
635         p += *p + 1;
636     
637     i = MIN(buflen - 1, *p);
638         if (i > 0) {
639                 memcpy(buffer, p + 1, i);
640                 buffer[i] = '\0';
641                 }
642         else {
643                 if (buflen > 1) {
644                         buffer[0] = '\0';
645                         return 0;
646                         }
647                 fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
648                 fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1);
649                 }
650     GlobalFree(hmem);
651
652     dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer);
653     return i;
654 }
655 \f
656 /**********************************************************************
657  *                      LoadMenu                [USER.150]
658  */
659 HMENU LoadMenu(HINSTANCE instance, char *menu_name)
660 {
661         HMENU                   hMenu;
662         HANDLE          hMenu_desc;
663         MENU_HEADER     *menu_desc;
664
665         if(debugging_menu){
666         printf("LoadMenu(%04X", instance);
667         PrintId(menu_name);
668         printf(")\n");
669         }
670         if (menu_name == NULL)
671                 return 0;
672
673         if ((hMenu_desc = RSC_LoadResource(instance, menu_name, (LPSTR) NE_RSCTYPE_MENU, NULL)) == (HANDLE) NULL)
674                 return 0;
675         
676         menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc);
677         hMenu = LoadMenuIndirect((LPSTR)menu_desc);
678         return hMenu;
679 }
680 \f
681 /**********************************************************************
682  *                                      LoadBitmap
683  */
684 HBITMAP 
685 LoadBitmap(HANDLE instance, LPSTR bmp_name)
686 {
687     HBITMAP hbitmap;
688     HANDLE rsc_mem;
689     HDC hdc;
690     long *lp;
691     int image_size;
692     int size;
693     
694     if(debugging_resource){
695         printf("LoadBitmap(%04X", instance);
696         PrintId(bmp_name);
697         printf(")\n");
698     }
699
700     if (!instance)
701     {
702         if (HIWORD((int)bmp_name)) return 0;  /* FIXME: should handle '#xxx' */
703         return OBM_LoadBitmap( LOWORD((int)bmp_name) );
704     }
705
706     rsc_mem = RSC_LoadResource(instance, bmp_name, (LPSTR) NE_RSCTYPE_BITMAP, 
707                                &image_size);
708     if (rsc_mem == (HANDLE)NULL) {
709         printf("LoadBitmap(%04X", instance);
710         PrintId(bmp_name);
711         printf(") NOT found!\n");
712         return 0;
713         }
714     lp = (long *) GlobalLinearLock(rsc_mem);
715     if (lp == NULL)
716     {
717         GlobalFree(rsc_mem);
718         return 0;
719     }
720     if (!(hdc = GetDC(0))) lp = NULL;
721     size = CONV_LONG (*lp);
722     if (size == sizeof(BITMAPCOREHEADER)){
723         CONV_BITMAPCOREHEADER (lp);
724         hbitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lp );
725     } else if (size == sizeof(BITMAPINFOHEADER)){
726         CONV_BITMAPINFO (lp);
727         hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp );
728     } else hbitmap = 0;
729     GlobalFree(rsc_mem);
730     ReleaseDC( 0, hdc );
731     return hbitmap;
732 }