I want to write a simple configurator program based on resources. I use Windows API function to update resources of stub.exe. Application shows no error, but resource isn't added (some times exe file gets corrupted!). When I open stub.exe in ResourceHacker there are no resources.
My code is:
#include <Windows.h>
#define LANGUAGEID 1033
HANDLE hUpdate;
char szStubPath[MAX_PATH];
char DeadCode[] = "0xDEADC0DE";
unsigned int error = 0;
int main()
{
GetCurrentDirectory(MAX_PATH, szStubPath);
lstrcat(szStubPath, "\\stub.exe");
hUpdate = BeginUpdateResource(szStubPath, FALSE);
if(hUpdate == NULL)
{
MessageBox(0, "BeginUpdateResource failed.", 0, MB_OK+MB_ICONERROR);
error = 1;
}
if(UpdateResource(hUpdate, RT_STRING, TEXT("CURRENT"), LANGUAGEID, &DeadCode, 11) == FALSE)
{
MessageBox(0, "UpdateResource failed.", 0, MB_OK+MB_ICONERROR);
error = 1;
}
if(EndUpdateResource(hUpdate, FALSE) == FALSE)
{
MessageBox(0, "EndUpdateResource failed.", 0, MB_OK+MB_ICONERROR);
error = 1;
}
if(error == 0)
{
MessageBox(0, "stub.exe - Resource added.", "Info", 0);
return EXIT_SUCCESS;
}
else
{
MessageBox(0, "stub.exe - Adding resource failed.", "Info", 0);
return EXIT_FAILURE;
}
}
There are no errors, but resource isn't added (some times exe file gets corrupted!), why? What is wrong?
Edit:
I want to add information that stub.exe is written in MASM32 and config.exe is written in Visual C++. Is there a chance that different programming languages makes problems?
Regards, David
Related
I am using the following code to check if a file is being used by another application:
HANDLE fh = CreateFile("D:\\1.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (fh == INVALID_HANDLE_VALUE)
{
MessageBox(NULL, "The file is in use", "Error", 0);
}
If the file is being used by another application, the message box is displayed. However, the message box is also displayed if the file does not exists!
So what should I do to solve this problem, should I also check if the file exists (using another function), or can the parameters of CreateFile() be changed to only return INVALID_HANDLE_VALUE if the file is in use and does exists?
If you wish to find out, which process has a file open, use the Restart Manager. The procedure consists of the following steps (as outlined in Raymond Chen's blog entry How do I find out which process has a file open?):
Create a Restart Manager session (RmStartSession).
Add a file resource to the session (RmRegisterResource).
Ask for a list of all processes affected by that resource (RmGetList).
Close the session (RmEndSession).
Sample code:
#include <Windows.h>
#include <RestartManager.h>
#pragma comment(lib, "Rstrtmgr.lib")
bool IsFileLocked( const wchar_t* PathName ) {
bool isFileLocked = false;
DWORD dwSession = 0x0;
wchar_t szSessionKey[CCH_RM_SESSION_KEY + 1] = { 0 };
if ( RmStartSession( &dwSession, 0x0, szSessionKey ) == ERROR_SUCCESS ) {
if ( RmRegisterResources( dwSession, 1, &PathName,
0, NULL, 0, NULL ) == ERROR_SUCCESS ) {
DWORD dwReason = 0x0;
UINT nProcInfoNeeded = 0;
UINT nProcInfo = 0;
if ( RmGetList( dwSession, &nProcInfoNeeded,
&nProcInfo, NULL, &dwReason ) == ERROR_MORE_DATA ) {
isFileLocked = ( nProcInfoNeeded != 0 );
}
}
RmEndSession( dwSession );
}
return isFileLocked;
}
You need to use GetLastError() to know why CreateFile() failed, eg:
// this is requesting exclusive access to the file, so it will
// fail if the file is already open for any reason. That condition
// is detected by a sharing violation error due to conflicting
// sharing rights...
HANDLE fh = CreateFile("D:\\1.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (fh == INVALID_HANDLE_VALUE)
{
switch (GetLastError())
{
case ERROR_PATH_NOT_FOUND:
case ERROR_FILE_NOT_FOUND:
MessageBox(NULL, "The file does not exist", "Error", 0);
break;
case ERROR_SHARING_VIOLATION:
MessageBox(NULL, "The file is in use", "Error", 0);
break;
//...
default:
MessageBox(NULL, "Error opening the file", "Error", 0);
break;
}
}
else
{
// the file exists and was not in use.
// don't forget to close the handle...
CloseHandle(fh);
}
I'm trying to do an automatic install for the NDIS filter driver.
Kernel debugging is enabled on my machine so driver signing is not required.
P.s. some of the code, I took from this question, but it's still doesn't work.
It gives me this dialog, where the default path to dir wrong.
Also, I watch this topic, but links there aren't workable.
How I can set a default path to .sys file?
Thanks.
....
DWORD size = 0;
isCopied = SetupCopyOEMInfA(pathToInf, // ( C:\[SomeDirs]\[driverInfFile.inf] )
pathToBin, // ( C:\[SomeDirs]\ ) here is driverSysFile.sys
SPOST_PATH,
SP_COPY_NEWER,
NULL,
0,
&size,
NULL);
....
INetCfg *pnc = NULL;
INetCfgClassSetup *pncClassSetup = NULL;
HRESULT hr;
....
hr = CoCreateInstance( CLSID_CNetCfg,
NULL, CLSCTX_INPROC_SERVER,
IID_INetCfg,
(void**)&pnc );
....
INetCfgLock *pncfglock = NULL;
pnc->QueryInterface(IID_INetCfgLock, (LPVOID*)&pncfglock);
pncfglock->AcquireWriteLock(5000, L"MY CLIENT", &szwrClient)
....
hr = pnc->QueryNetCfgClass ( &GUID_DEVCLASS_NETSERVICE,
IID_INetCfgClassSetup,
(void**)&pncClassSetup );
....
OBO_TOKEN OboToken;
ZeroMemory( &OboToken, sizeof(OboToken) );
OboToken.Type = OBO_USER;
INetCfgComponent* NDIS_Component;
//
// I read, that this 2 param both need for automatic setup, and if one is set,
// the second must be setted too.
// But the second[pszwAnswerSections] need to be list of sections in the inf file.
// And it not so cool to parse inf file manually, why OS cant do this???
LPCWSTR pszwAnswerFile = NULL;
LPCWSTR pszwAnswerSections = NULL;
//
// this call fails:
hr = pncClassSetup->Install(COMPONENT_ID,
&OboToken,
NSF_POSTSYSINSTALL,
0,
pszwAnswerFile,
pszwAnswerSections ,
&NDIS_Component);
You can use below code for installing protocol driver. I had created a win32 application for installing protocol driver and assumed that inf and driver file are at same location where executable binary is present. Sometime there are chances that driver file does not get copied so copy it via code. I had used this and it is working perfectly.
#define NDISPROT_SERVICE_PNP_DEVICE_ID_A "PROTOCOL DEVICE NAME"
HRESULT InstallSpecifiedComponent(LPTSTR lpszInfFile, LPTSTR lpszPnpID, const GUID *pguidClass)
{
INetCfg *pnc = NULL;
LPTSTR lpszApp = NULL;
HRESULT hr = S_OK;
hr = HrGetINetCfg(TRUE, APP_NAME, &pnc, &lpszApp);
if(S_OK == hr)
{
//
// Install the network component.
//
PrintMsg(NULL, L"InstallSpecifiedComponent : HrGetINetCfg success.\n");
hr = HrInstallNetComponent(pnc, lpszPnpID, pguidClass, lpszInfFile);
if((S_OK == hr) || (NETCFG_S_REBOOT == hr))
{
PrintMsg(NULL, L"InstallSpecifiedComponent : HrInstallNetComponent success.\n");
hr = pnc->Apply();
if (S_OK == hr)
{
PrintMsg(NULL, L"InstallSpecifiedComponent : Apply success.\n");
}
else
{
PrintMsg(NULL, L"InstallSpecifiedComponent : Apply fail with error code %d.\n", GetLastError());
}
}
else
{
PrintMsg(NULL, L"InstallSpecifiedComponent : HrInstallNetComponent fail with error code %d.\n", GetLastError());
if(HRESULT_FROM_WIN32(ERROR_CANCELLED) != hr)
{
PrintMsg(hr, L"InstallSpecifiedComponent : Couldn't install the network component.");
}
}
HrReleaseINetCfg(pnc, TRUE);
}
else
{
PrintMsg(NULL, L"InstallSpecifiedComponent : HrGetINetCfg fail with error code %d.\n", GetLastError());
if((NETCFG_E_NO_WRITE_LOCK == hr) && lpszApp )
{
PrintMsg(hr, L"InstallSpecifiedComponent : %s currently holds the lock, try later.", lpszApp);
CoTaskMemFree(lpszApp);
}
else
{
PrintMsg(hr, L"InstallSpecifiedComponent : Couldn't the get notify object interface.");
}
}
PrintMsg(NULL, L"InstallSpecifiedComponent : InstallSpecifiedComponent exit.\n");
return hr;
}
DWORD InstallDriver()
{
DWORD nResult = 0;
HRESULT hr = S_OK;
memset(g_szInfFileFullPath, 0, _MAX_PATH * sizeof(TCHAR));
// Get Path to Service INF File
// The INF file is assumed to be in the same folder as this application.
// Below function returns full path for inf file present in same folder
nResult = GetInfFilePath(g_szInfFileFullPath, MAX_PATH);
if(0 == nResult)
{
return nResult;
}
hr = InstallSpecifiedComponent(g_szInfFileFullPath, NDISPROT_SERVICE_PNP_DEVICE_ID, &GUID_DEVCLASS_NETTRANS);
if(S_OK == hr)
{
PrintMsg(NULL, L"InstallDriver : InstallSpecifiedComponent success.\n");
nResult = 1;
}
else
{
PrintMsg(hr, L"InstallDriver : InstallSpecifiedComponent fail with error code %d.\n", GetLastError());
}
PrintMsg(NULL, L"InstallDriver : InstallDriver exit.\n");
return nResult;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
//Driver Installation.
nRetCode = InstallDriver();
if(1 == nRetCode)
{
Sleep(1000 * 2);
// Sometimes driver file does not get copied into systme32\drivers folder, so just for precaution copy it using code
if(CopyDrvFile())
{
system("net start ekaprot6");
}
}
return nRetCode;
}
Unhandled exception error thrown while running the program
Following is the source code of my program, there's no compilation error but when i run it i get the exception Runtime error as in the attached image.
Blockquote
First-chance exception at 0x00000000 in all5.1.exe: 0xC0000005: Access violation executing location 0x00000000.
Unhandled exception at 0x778F1A91 in all5.1.exe: 0xC0000005: Access violation executing location 0x00000000.
Blockquote
#include <conio.h>
#include <allegro5\allegro.h>
#include <allegro5\allegro_native_dialog.h>
#include <allegro5\allegro_font.h>
#include <allegro5\allegro_ttf.h>
#include <allegro5\allegro_image.h>
#include <allegro5\allegro_primitives.h>
const int SCREEN_H = 690;
const int SCREEN_W = 1350;
class background
{
private: int advt_x = 1000, advt_y = SCREEN_H - 100, nw_m_x = 1350; //data cannot be accessed from outside the class
public: ALLEGRO_FONT *size_20 = al_load_font("digital-7.ttf", 20, 2); //loading font file for advt() and nw_title()
public: ALLEGRO_FONT *size_15 = al_load_font("digital-7.ttf", 15, 1); //loading font file for nw_marquee()
public: void bground()
{
ALLEGRO_BITMAP *bgr = al_load_bitmap("bground.jpg"); //loading the background vertex image
if (bgr == NULL) //checking whether the image loaded successfully or not
{
al_show_native_message_box(NULL, "Error", NULL, "Fatal error: Backgroung Missing from disk!!!", NULL, NULL); //if image didn't loaded then print the error message
}
al_draw_bitmap(bgr, 0, 0, NULL); //printing the background image
}
public: void studio()
{
ALLEGRO_BITMAP *anch = al_load_bitmap("anchor.jpg");
if (anch == NULL) //checking whether the image loaded successfully or not
{
al_show_native_message_box(NULL, "Error", NULL, "Fatal error: Anchor Missing from disk!!!", NULL, NULL); //if image didn't loaded then print the error message
}
al_draw_bitmap(anch, SCREEN_W-300, SCREEN_H-500, NULL); //printing the anchor image
}
public: void news_info()
{
ALLEGRO_BITMAP *nwinfo = al_load_bitmap("news_image.jpg");
if (nwinfo == NULL) //checking whether the image loaded successfully or not
{
al_show_native_message_box(NULL, "Error", NULL, "Fatal error: News Media Missing from disk!!!", NULL, NULL); //if image didn't loaded then print the error message
}
al_draw_bitmap(nwinfo, 0, 200, NULL); //printing the News Media
}
public: void ch_logo()
{
ALLEGRO_BITMAP *chlogo = al_load_bitmap("logo_header.jpg");
if (chlogo == NULL) //checking whether the image loaded successfully or not
{
al_show_native_message_box(NULL, "Error", NULL, "Fatal error: News Media Missing from disk!!!", NULL, NULL); //if image didn't loaded then print the error message
}
al_draw_bitmap(chlogo, SCREEN_W-110, 0, NULL); //printing the News Media
}
public: void nw_title()
{
al_draw_rectangle(0, 0, SCREEN_W-110, 72, al_map_rgb(0, 255, 0), 1.0);
al_draw_text(size_20, al_map_rgb(128, 50, 30), 0, 0, 0, "Violence in a Restaurant over the payment of Bill amounting INR 260."); //printing text
}
public: void nw_marquee()
{
int nw_m_text_len = al_get_text_width(size_15, "All news headlines will be displayed in marquee here.");
if (nw_m_x == (0 - nw_m_text_len))
{
nw_m_x = 1000;
}
al_draw_filled_rectangle(0, SCREEN_H-190, SCREEN_W, SCREEN_H-100, al_map_rgb(0, 255, 0));
al_draw_text(size_15, al_map_rgb(128, 50, 30), nw_m_x, SCREEN_H - 140, 0, "All news headlines will be displayed in marquee here.");
nw_m_x--;
}
public: void advt()
{
al_draw_filled_rectangle(0, SCREEN_H-99, SCREEN_W, SCREEN_H, al_map_rgb(90, 110, 0));
al_draw_text(size_20, al_map_rgb(128, 50, 30), advt_x, SCREEN_H-50, 0, "Ads will be shown here.");
advt_x--;
}
}bg;
int main()
{
ALLEGRO_DISPLAY *display = NULL;
if (!al_init())
{
al_show_native_message_box(NULL, "Init error", NULL, "Allegro failed to initialise!!! Program is exiting.", NULL, NULL);
return -1;
}
display = al_create_display(1350, 690);
al_set_window_position(display, 0, 0);
al_set_window_title(display, "New Window");
al_init_font_addon();
al_init_image_addon();
al_init_primitives_addon();
bg.bground();
bg.studio();
bg.ch_logo();
bg.news_info();
while (1 == 1)
{
bg.nw_title();
bg.advt();
bg.nw_marquee();
al_flip_display(); //print from backBuffer to screen and makes things visible
al_rest(3.0);
al_destroy_display(display);
}
_getch();
return 0;
}
Found the error, right after initializing the font add-on, you need to initialize the ttf add-on with al_init_ttf_addon(). What happens is that the font add-on alone does not know how to read the different formats. So it was failing silently when you tried to load the *.ttf fonts.
Your code is a mess. The formatting is bad, and there are quite a few rampant memory leaks.
Every time you call one of your void functions you load a bitmap but never destroy it with al_destroy_bitmap. This means it leaks an entire ALLEGRO_BITMAP every time. Eventually you will run out of memory and it will return NULL.
rlam is correct about calling al_init_font_addon after al_init. If you're using ttf fonts, you also need to call al_init_ttf_addon.
Something else to be wary of is global objects that load allegro resources in a constructor. These will be loaded before al_init is called, and so they will fail.
I'm trying to make DuplicateHandle() for a file that another process writes. I succeeded, but I get the position of the owner process. After I seek to the beginning it seeks also in the owner process. Can I somehow seek without changing the first process's progress?
EDIT:
Another application opens this file without CreateFile. Is thare a way to read the file form the begining with ReadFile, without seeking manually?
EDIT again:
There isn't a way to read only from one side with duplicated handle. Thanks for helping.
From MSDN:
The duplicate handle refers to the same object as the original handle. Therefore, any changes to the object are reflected through both handles. For example, if you duplicate a file handle, the current file position is always the same for both handles. For file handles to have different file positions, use the CreateFile function to create file handles that share access to the same file.
Instead of DuplicateHandle, you must call CreateFile in both process, with the right combination of access mode and sharing flag. MSDN has the full set of rules, here is a combination that works :
Writer process :
HANDLE file = CreateFile(..., GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, ...);
Reader process :
HANDLE file = CreateFile(..., GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, ...);
If you need to play with the flags, here is the (crude) test application I wrote to answer your question :
// 2process1file.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#define NUMBER_OF_LINES 100
#define IO_PERIOD 250
static const char message[] = "The quick brown fox jumps over the lazy dog.\n";
HANDLE file = INVALID_HANDLE_VALUE;
BOOL CtrlHandler(DWORD ctltype)
{
if(file != INVALID_HANDLE_VALUE)
{
CloseHandle(file);
file = INVALID_HANDLE_VALUE;
}
return FALSE;
}
int _tmain(int argc, _TCHAR* argv[])
{
if(argc == 3)
{
DWORD access = GENERIC_READ;
DWORD share = FILE_SHARE_READ;
bool is_writer = false;
if((*argv[1]|' ') == 'w')
{
access |= GENERIC_WRITE;
is_writer = true;
}
else
{
share |= FILE_SHARE_WRITE;
}
file = CreateFile(argv[2], access, share, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(file != INVALID_HANDLE_VALUE)
{
DWORD nbytes = 1;
SetFilePointer(file, 0, 0, FILE_BEGIN); //Redundant when writing
for(int i=0; (i<NUMBER_OF_LINES) && nbytes; ++i) {
if(is_writer) {
if(WriteFile(file, message, sizeof(message)-1, &nbytes, 0) == 0)
{
//Write failed somehow
break;
}
//Sleep(INFINITE);
if(i%25 == 0) printf("%d\n", i);
} else {
char buffer[sizeof message] = "";
if(ReadFile(file, buffer, sizeof(buffer)-1, &nbytes, 0) && nbytes) {
buffer[sizeof(buffer)-1] = 0;
printf(buffer);
} else {
//Read failed somehow
break;
}
}
Sleep(IO_PERIOD);
}
CloseHandle(file);
file = INVALID_HANDLE_VALUE;
}
}
else
{
wprintf(L"Usage : %s [w|r] filename\n");
}
return 0;
}
int rename_file()
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
hFind = FindFirstFile(L"\\Hard Disk\\*.*", &FindFileData);
LPTSTR oldfilename;
LPTSTR newfilename;
if (hFind == INVALID_HANDLE_VALUE)
{
printf ("FindFirstFile failed (%d)\n", GetLastError());
return 0;
}
else
{
int i=1000;
while (FindNextFile(hFind, &FindFileData) != 0)
{
_tprintf (TEXT("The first file found is %s\n"),FindFileData.cFileName);
oldfilename =FindFileData.cFileName;
StringCchPrintf(newfilename, 30, TEXT("%s\\newfile_%d.txt"),dirname, i);
BOOL rs = MoveFile(oldfilename,newfilename);
i++;
}
FindClose(hFind);
return 1;
}
}
i am unable to rename file ,i am working on wince 6 ,while debugging at StringCchPrintf iam getting exception in coredll.dll can any one help me ....
You have not allocated any buffer for newFileName, so when you use it in the StringCchPrintf it's just an uninitialized pointer.
Try this:
TCHAR newFile[260]; // or whatever length you wish
LPTSTR newfilename = &newFile[0];
Also you should check the return code from MoveFile, and output something sensible on error. Make a habit of doing this for all your function calls that can return an error.