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