We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Export a resource

zeurx
zeurx asked
on
Medium Priority
305 Views
Last Modified: 2013-11-20
i have been trying to export a resource to a file for the past few weeks. When i try to run the exporting code in my dll it can not get the resource and returns a NULL error.

resource = bmp
bmp for wallpaper

<code>
    // Set File //
     
     TCHAR WinDir[INFO_BUFFER_SIZE];
     GetWindowsDirectory(WinDir,sizeof(WinDir));
     CString Wallpaper; Wallpaper.Format("%s",WinDir);
     CString sHeight; sHeight.Format("%i",height); CString sWidth; sWidth.Format("%i",width);
     Wallpaper += "\\Shadower-"+sWidth+"x"+sHeight+".bmp";
     AfxMessageBox(Wallpaper);
     // Get Resource //
     HMODULE hModule = LoadLibrary("Shadower.dll");
     CString size; size.Format("%i",width);
     LPCTSTR lpFile; lpFile = "SHADOWBG_"; lpFile =+ (char *) (LPCTSTR) size;
     AfxMessageBox(lpFile,MB_OK,NULL);
     HRSRC hRes = FindResource(hModule,lpFile,RT_BITMAP);
     HGLOBAL hResLoad = LoadResource(hModule,hRes);
     LPVOID bmpResource = LockResource(hResLoad);
     // Save to Bmp //
     DWORD Size = 0;
     memcpy (&Size, bmpResource, sizeof (DWORD));
     DWORD written = 0;
     LPSTR Wall = (char *) (LPCTSTR) Wallpaper;
     HANDLE hFile = CreateFile(Wall,
                                        GENERIC_WRITE,
                                        FILE_SHARE_READ,
                                        NULL,
                                        CREATE_ALWAYS,
                                        FILE_ATTRIBUTE_READONLY,
                                        NULL);
     WriteFile(hFile, "BM", 2, &written, NULL);
     WriteFile(hFile, bmpResource, Size, &written, NULL);
     UnlockResource(hResLoad);
     FreeLibrary(hModule);
     // Set Wallpaper //
     Reg.SetRootKey(HKEY_CURRENT_USER);
     Reg.SetKey("Control Panel\\Desktop",0);
     Reg.WriteString("Wallpaper",Wallpaper);
     Reg.WriteString("WallpaperStyle","2");
     SystemParametersInfo(SPI_SETDESKWALLPAPER,0,NULL,SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);
when i run this code i get an error...
this is what i use to get to this function...
#include "..\dll\Wallpaper.h"
          CWallpaper Wallpaper;
          Wallpaper.ExtractBMP(768,1024);
</code>

Could someone look through this code and tell me what might be going wrong.
the resource name im trying to get is "SHADOWBG_1024" and i would like to make the numbers in that change with the screen size, i have the code for that thow.
Comment
Watch Question

Commented:
Hi zerux,

You need to allocate the lpFile
Instead of
> LPCTSTR lpFile; lpFile = "SHADOWBG_"; lpFile =+ (char *) (LPCTSTR) size;
try
  char lpFile[MAX_PATH] = "SHADOWBG_"; lstrcat(lpFile, size.GetBuffer());

Where do you get the error?  hRes is NULL?

Commented:
sorry, I misspelled yor nick, it's zeurx. my appologies

Author

Commented:
i get the error in the CreateFile part

Author

Commented:
and in Dissasembly
100062BB  mov         ebx,dword ptr [edi]

Commented:
You said
>When i try to run the exporting code in my dll it can not get the resource and returns a NULL error.
and
>i get the error in the CreateFile part.
I don't get it. Who retunrs NULL? As long as I know CreateFile returns INVALID_HANDLE_VALUE (-1) on error. Do you have an access violation exception? Please give more details, some variable values during your error...
CERTIFIED EXPERT

Commented:
hm ... didn't test it yet, but maybe it's not possible to create a file as 'read-only' for 'write' access ...

IMO you should set the file to 'read-only' after you have written it ...

ZOPPO

Commented:
Zoppo, it is possible. I've tested ;)
CERTIFIED EXPERT

Commented:
ok ... thanks :o)

ZOPPO

Author

Commented:
ok i have changed my code to the following...

        // Set File //
      TCHAR WinDir[INFO_BUFFER_SIZE];
      GetWindowsDirectory(WinDir,sizeof(WinDir));
      CString Wallpaper; Wallpaper.Format("%s",WinDir);
      CString sHeight; sHeight.Format("%i",height); CString sWidth; sWidth.Format("%i",width);
      Wallpaper += "\\Shadower-"+sWidth+"x"+sHeight+".bmp";
      // Get Resource //
      HMODULE hModule = LoadLibraryEx("Shadower.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
      CString size; size.Format("%i",width);
      char lpFile[MAX_PATH] = "SHADOWBG_"; lstrcat(lpFile, size.GetBuffer());
      HRSRC hRes = FindResource(hModule,lpFile,RT_BITMAP);
      HGLOBAL hResLoad = LoadResource(hModule,hRes);
      LPVOID bmpResource = LockResource(hResLoad);
      // Save to Bmp //
      DWORD Size = *(DWORD *)bmpResource;
      DWORD written = 0;
      LPSTR Wall = (char *) (LPCTSTR) _T(Wallpaper);
      DeleteFile(Wallpaper);
      HANDLE hFile = CreateFile(Wall,
                                                GENERIC_WRITE,// | GENERIC_READ,
                                                FILE_SHARE_WRITE,//FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                                NULL,
                                                CREATE_ALWAYS,
                                                FILE_ATTRIBUTE_NORMAL,
                                                NULL);
//      WriteFile(hFile, "BM", 2, &written, NULL);
      WriteFile(hFile, bmpResource, Size, &written, NULL);

      UnlockResource(hResLoad);
      FreeLibrary(hModule);
      WinExec("mspaint "+Wallpaper,SW_SHOW);
      // Set Wallpaper //
/*      Reg.SetRootKey(HKEY_CURRENT_USER);
      Reg.SetKey("Control Panel\\Desktop",0);
      Reg.WriteString("Wallpaper",Wallpaper);
      Reg.WriteString("WallpaperStyle","2");
      SystemParametersInfo(SPI_SETDESKWALLPAPER,0,NULL,SPIF_SENDCHANGE|SPIF_UPDATEINIFILE);*/

In this i delete a file (i might add code to is if the file exsits and delete if it does and i get the following error...

      DeleteFile(Wallpaper);

Unhandled exception at 0x100062b2 (Shadower.dll) in Shadower.exe: 0xC0000005: Access violation reading location 0x00000000.

and if i comment the line out i get...

      HANDLE hFile = CreateFile(Wall,
                                                GENERIC_WRITE,// | GENERIC_READ,
                                                FILE_SHARE_WRITE,//FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                                NULL,
                                                CREATE_ALWAYS,
                                                FILE_ATTRIBUTE_NORMAL,
                                                NULL);

Unhandled exception at 0x100062bf (Shadower.dll) in Shadower.exe: 0xC0000005: Access violation reading location 0x00000000.

note the parts comment out!

it does not create a file at all.

Author

Commented:
     LPVOID Text = _T("Test");
      DWORD Size = 4;
      DWORD written = 0;
      LPSTR File = _T("C:\\Test.file.txt");
      DeleteFile(File);
      HANDLE hFile = CreateFile(File,
                                                GENERIC_WRITE,// | GENERIC_READ,
                                                FILE_SHARE_WRITE,//FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                                                NULL,
                                                CREATE_ALWAYS,
                                                FILE_ATTRIBUTE_NORMAL,
                                                NULL);
      WriteFile(hFile, Text, Size, &written, NULL);
      CloseHandle(hFile);

This is a demo program that shows one part of shadower and this is to write test to the file c:\test.file.txt and IT WORKS!!! why dosent the other one write/create anything?

Author

Commented:
Update:
      I can not find the resource/bmp with this code... anyone know why

Author

Commented:
     // Get Resource //
      HMODULE hModule = LoadLibraryEx("Shadower.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
      CString size; size.Format("%i",width);
      char lpFile[MAX_PATH] = "SHADOWBG_"; lstrcat(lpFile, size.GetBuffer());
      HRSRC hRes = FindResource(hModule,"SHADOWBG_1024",RT_BITMAP);
      if (hRes == NULL)
            AfxMessageBox("Bitmap not found");
      HGLOBAL hResLoad = LoadResource(hModule,hRes);
      if (hResLoad == NULL)
            AfxMessageBox("Bitmap not loaded");
CERTIFIED EXPERT

Commented:
Hi again,

excuse me, but I think you should at first clean up a little bit of your code...

i.e. the lines
>     CString Wallpaper; Wallpaper.Format("%s",WinDir);
>     CString sHeight; sHeight.Format("%i",height); CString sWidth; sWidth.Format("%i",width);
>     Wallpaper += "\\Shadower-"+sWidth+"x"+sHeight+".bmp";
can easily be written as i.e.
>     CString Wallpaper;
>     Wallpaper.Format( "%s\\Shadower-%ix%i.bmp", WinDir, width, height );

lines:
 >    CString size; size.Format("%i",width);
 >    char lpFile[MAX_PATH] = "SHADOWBG_"; lstrcat(lpFile, size.GetBuffer());
could be written i.e. as
>     CString sName;
>     sName.Format( "SHADOWBG_%i", width );
 
those mixing up of 'CString's and 'char*' functions can lead to problems and aren't good to read


Further a problem IMO is that most unlikely the name of the resource is really something like
'SHADOWBG_1024' ... I guess that's the resource ID of the resource in the .dll, but the resource
ID is not a name. In the .dll's 'resource.h' file you'll find a '#define SHADOWBG_1024 <xyz>' where
<xyz> is a hex number ... this number is what you'll have to specify in FindResource to find the
resource.

In addition I'd suggest you to do a bit more checking on the return values, i.e. code like this
>     ...
>     HMODULE hModule = LoadLibraryEx("Shadower.dll",NULL,LOAD_LIBRARY_AS_DATAFILE);
>     ...
>     HRSRC hRes = FindResource(hModule,lpFile,RT_BITMAP);
>     HGLOBAL hResLoad = LoadResource(hModule,hRes);
>     LPVOID bmpResource = LockResource(hResLoad);
>     ...
would make me nervous ;o)

ZOPPO

Author

Commented:
(MFC)
in HRSRC hRes = FindResource(hModule,sName,RT_BITMAP);
(ASM)
100075F3  call        dword ptr [__imp__FindResourceA@12 (10021254h)]
100075F9  mov         dword ptr [hRes],eax

reutrns eax = 00000000

than it calls the messagebox

any ideas or do i need to dig deeper and if so any seguestions on how to dig
CERTIFIED EXPERT

Commented:
Did you try to use the resource ID's number instead of the name?

I really guess that's the problem here ...

Search in the resource.h file of the shadower.dll for the ID 'SHADOWBG_1024'.

Use the number defined for this ID as sName as described in MSDN about FindResource ...

ZOPPO

Author

Commented:
yes its "#30002" and then it writes the file but writes the wrong stuff and i do not know where it gets the stuff from now.

HRSRC hRes = FindResource("Shadower.dll","#3002",RT_BITMAP);

I also wonder if i can just save the bitmap because this code is in shadower and is very poor writen to call a resource that i sould be able to get another way that would be more efficent.  If you know how to open a bmp and save it that would also help.  I think that the code below should work but i have no access to vs right now so just of the top of my head.

BITMAP hRes; hRes.LoadBitmap(sName); hRes.SaveBitmap(Wallpaper);

would this code work or not... would this method work or not

Author

Commented:
ok i have finaly got time to work on it and this is what i come up with.

1.
      // Set File //
      TCHAR WinDir[INFO_BUFFER_SIZE];
      GetWindowsDirectory(WinDir,sizeof(WinDir));
      CString Wallpaper;
      Wallpaper.Format("%s\\Shadower-%ix%i.bmp", WinDir, width, height);
      // Get Resource //
      CString sName;
      sName.Format("SHADOWBG_%i",width);
      CBitmap hRes;
      hRes.LoadBitmap(sName);
      HBITMAP hBmp;
      hBmp = hRes.operator HBITMAP();
      CImage hImg;
      hImg.Attach(hBmp);
      // Save Bitmap //
      DeleteFile(Wallpaper);
      HANDLE hFile = CreateFile(Wallpaper,
                                                GENERIC_WRITE,
                                                FILE_SHARE_WRITE,
                                                NULL,
                                                CREATE_ALWAYS,
                                                FILE_ATTRIBUTE_NORMAL,
                                                NULL);
      CloseHandle(hFile);
      hImg.Save(Wallpaper);
      hImg.Detach();

2.
      // Set File //
      
      TCHAR WinDir[INFO_BUFFER_SIZE];
      GetWindowsDirectory(WinDir,sizeof(WinDir));
      CString Wallpaper;
      Wallpaper.Format("%s\\Shadower-%ix%i.bmp", WinDir, width, height);
      // Get Resource //
      CString sName;
      sName.Format("SHADOWBG_%i",width);
      CBitmap hRes;
      hRes.LoadBitmap(sName);
      HBITMAP hBmp;
      hBmp = hRes.operator HBITMAP();
      CImage hImg;
      hImg.Attach(hBmp);
      // Save Bitmap //
      hImg.Save(Wallpaper);
      hImg.Detach();

but with this code it dosent load or save. dont know what, the bitmap because the file is 0kb
CERTIFIED EXPERT
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.