WinINet trouble downloading file to client? - c++

I'm curious why I'm having trouble with this function. I'm downloading a PNG file on the web to a destination path. For example, downloading the Google image to the C: drive:
netDownloadData("http://www.google.com/intl/en_ALL/images/srpr/logo1w.png", "c:\file.png");
The file size is correct after downloading. Nothing returning false. When I try opening it it won't show the image. Any ideas are helpful. Thanks!
Here's the code:
bool netDownloadData(const char *strSourceUrl, const char *strDestPath)
{
HINTERNET hINet = NULL;
HINTERNET hFile = NULL;
char buffer[1024];
DWORD dwRead;
String sTemp;
FILE *fp = NULL;
DWORD size = 0;
// Open a new internet session
hINet = netInit();
if (hINet == NULL) {
sprintf(buffer, "Initializing WinINet failed.", strSourceUrl);
utilLog(buffer);
netCloseHandle(hINet);
return false;
}
// Open the requested url.
hFile = netOpenUrl(hINet, strSourceUrl);
if (hFile == NULL) {
sprintf(buffer, "URL failed upon loading: %s\n", strSourceUrl);
utilLog(buffer);
netCloseHandle(hINet);
return false;
}
// Read file.
while (InternetReadFile(hFile, buffer, 1023, &dwRead))
{
if (dwRead == 0)
break;
buffer[dwRead] = 0;
sTemp += buffer;
size += dwRead;
}
// Load information to file.
fp = fopen(strDestPath, "wb");
if (fp == NULL)
return false;
fwrite(sTemp, size, 1, fp);
fclose(fp);
InternetCloseHandle(hFile);
InternetCloseHandle(hINet);
return true;
}

What data type is String? Avoid storing binary data in strings because NULLs in the data can potentially cause problems. Just write the buffer as and when you read it:
// Load information to file.
fp = fopen(strDestPath, "wb");
if (fp == NULL)
return false;
// Read file.
while (InternetReadFile(hFile, buffer, 1024, &dwRead))
{
if (dwRead == 0)
break;
fwrite(buffer, dwRead, 1, fp);
}
fclose(fp);

It looks like your second and third args to fwrite are transposed. See fwrite docs for explanation.
try:
fwrite(sTemp, 1, size, fp);

Related

auxDIBImageLoad returns null

Hi i am doing a project with opengl
What I'm stuck with is that the method 'auxDIBImageLoad' always returns null even if the file exists.
My code is below:
AUX_RGBImageRec *LoadBMPFile(char *filename)
{
FILE *hFile = NULL;
if (!filename) return NULL;
hFile = fopen(filename, "r");
if (hFile)
{
printf("file opened\n");
fclose(hFile);
if (!auxDIBImageLoad(filename)) {
printf("but file is null\n");
}
return auxDIBImageLoad( filename );
}
printf("file open failed\n");
return NULL;
}
Then the log is below:
file opened
but file is null
load bmp failed
I already searched for fixing it so that I already set to Multibyte char set.
But it doesn't work after setting that.
Please help me.

Unable to Read from File while using ReadFIle() function in C++

I am facing some issues while reading data from file using ReadFile() function of C++ (Microsoft specific probably).
Here is my code
Write On File
void ClientA::SharePublicKey()
{
printf("Sharing Public Key\n");
HANDLE hFile = NULL;
hFile = CreateFile(TEXT("D:\\My_Proj\\shared\\PublicKeyB.txt"), // name of the write
GENERIC_WRITE, // open for writing
FILE_SHARE_WRITE, // do not share
NULL, // default security
CREATE_NEW, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
//DisplayError(TEXT("CreateFile"));
//_tprintf(TEXT("Terminal failure: Unable to open file \"%s\" for write.\n"), argv[1]);
return;
}
// _tprintf(TEXT("Writing %d bytes to %s.\n"), dwBytesToWrite, argv[1]);
bool bErrorFlag = WriteFile(
hFile, // open file handle
pbPublicKey, // start of data to write
dwPublicKeyLen, // number of bytes to write
&lpNumberOfBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
if (FALSE == bErrorFlag)
{
// DisplayError(TEXT("WriteFile"));
printf("Terminal failure: Unable to write to file.\n");
return;
}
else
{
if (lpNumberOfBytesWritten != dwPublicKeyLen)
{
// This is an error because a synchronous write that results in
// success (WriteFile returns TRUE) should write all data as
// requested. This would not necessarily be the case for
// asynchronous writes.
printf("Error: dwBytesWritten != dwBytesToWrite\n");
}
else
{
// _tprintf(TEXT("Wrote %d bytes to %s successfully.\n"), dwBytesWritten, argv[1]);
}
}
CloseHandle(hFile);
}
Read That File
void ClientA::ReadPublicKeyOfOtherPeer()
{
HANDLE hFile = NULL;
DWORD dwBytesRead = 0;
BYTE* ReadBuffer = NULL;
OVERLAPPED ol = {0};
hFile = CreateFile(TEXT("D:\\My_Proj\\shared\\PublicKeyB.txt"), // file to open
GENERIC_READ, // open for reading
FILE_SHARE_READ, // share for reading
NULL, // default security
OPEN_EXISTING, // existing file only
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, // normal file
NULL // no attr. template
);
if (hFile == INVALID_HANDLE_VALUE)
{
_tprintf(TEXT("CreateFile\n"));
_tprintf(TEXT("Terminal failure: unable to open file \"%s\" for read.\n"));
printf("Error %x\n", GetLastError());
return;
}
if( FALSE == ReadFile(hFile, ReadBuffer, dwPublicKeyLen, &lpNumberOfBytesWritten, &ol) )
{
// DisplayError(TEXT("ReadFile"));
printf("Terminal failure: Unable to read from file.\n GetLastError=%08x\n", GetLastError());
CloseHandle(hFile);
return;
}
if (dwBytesRead > 0 && dwBytesRead <= dwPublicKeyLen-1)
{
ReadBuffer[dwBytesRead]='\0'; // NULL character
//_tprintf(TEXT("Data read from %s (%d bytes): \n"), argv[1], dwBytesRead);
printf("%s\n", ReadBuffer);
}
else if (dwBytesRead == 0)
{
//_tprintf(TEXT("No data read from file %s\n"), argv[1]);
}
else
{
// printf("\n ** Unexpected value for dwBytesRead ** \n");
}
retrievedPublicByteArray = ReadBuffer;
CloseHandle(hFile);
}
By SharePublicKey method I am saving the data in a file. And I have checked that it successfully saves data on the file and the data on the files are seems to be valid.
And by ReadPublicKeyOfOtherPeer method I am reading the file which was previously saved. But reading is not successful In out put I found the following line -
Terminal failure: Unable to read from file.
GetLastError=000003e6
You are passing uninitialized pointer ReadBuffer to ReadFile. You need a buffer that is large enough to receive the results.

cannot write binary data in a file using c

I am using vs2010 in an windows vista os the problem is that i want to read and exe file encrypt it and store it but when i write the data back nothing gets inserted i mean the file is created but no errors and the file is empty and i have done it a thousand times and it works on eclipse but not on vs2010 and i need to port it into a gui can anyone please redirect me where i am wrong
FILE *pFile, *file;
size_t result;
pFile = fopen(fName, "r+b");
if (pFile==NULL) {MessageBox(NULL, L"Could not open file", L"Information", MB_ICONERROR); return FALSE;}
fseek(pFile, 0 ,SEEK_END);
sData->fSize = ftell(pFile);
rewind(pFile);
sData->fbuffer = (unsigned char *) malloc(sizeof(char) * sData->fSize);
if (sData->fbuffer == NULL) {MessageBox(NULL, L"Memory error", L"Information", MB_ICONERROR); fclose(pFile); return FALSE;}
file = fopen("out.txt", "w+b");
while ((result = fread(sData->fbuffer, 1, sData->fSize, file)) > 0) {
if (!(fwrite(sData->fbuffer, 1, result, file))) {
MessageBox(NULL, L"Write error", L"Information", MB_ICONERROR);
}
fclose(file);
}
fclose(file);
//result = fread(sData->fbuffer, 1, sData->fSize, pFile);
//if (result != sData->fSize) {MessageBox(NULL, L"Read error", L"Information", MB_ICONERROR); fclose(pFile); return FALSE;}
fclose (pFile);
return TRUE;
EDIT
I am really sorry the problem is with the location of the file it is in unicode format where as fopen accepts ascii and the location only shows C I have to convert it to get the proper result thanks
You would want to use pFile instead of file in fread().
//---------------------------------------------------- pFile not file
while ((result = fread(sData->fbuffer, 1, sData->fSize, pFile)) > 0) {
if (!(fwrite(sData->fbuffer, 1, result, file))) {
MessageBox(NULL, L"Write error", L"Information", MB_ICONERROR);
}
fclose(file);
}
I think the file that you are opening for read is not Ascii, so you assumption of calculation of file size based on size of char is wrong.
if you calculate right size of file in bytes and read and write those many bytes you should be fine.
You are reading and writing to/from the same file.
while ((result = fread(sData->fbuffer, 1, sData->fSize, file)) > 0) {
if (!(fwrite(sData->fbuffer, 1, result, file))) {
Since you just opened this file it reads nothing, so nothing is written as well.
From the man page:
w+ or wb+ or w+b
Truncate to zero length or create file for update.

Unable to open file using CreateFile function

Ok so I've been following this tutorial: http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=4422&lngWId=3
And so far I've gotten everything to work, up until I need the program to load in a .raw audio file.
Here's the relevant code:
LPSTR loadAudioBlock(const char* filename, DWORD* blockSize)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
DWORD size = 0;
DWORD readBytes = 0;
void* block = NULL;
//open the file
if((hFile = CreateFile((LPCWSTR)filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
return NULL;
// get it's size, allocate memory, and then read it into memory
size = GetFileSize(hFile, NULL);
block = HeapAlloc(GetProcessHeap(), 0, size);
ReadFile(hFile, block, size, &readBytes, NULL);
CloseHandle(hFile);
*blockSize = size;
return (LPSTR)block;
}
And then my main function which calls it:
int _tmain(int argc, _TCHAR* argv[])
{
HWAVEOUT hWaveOut; //device handle
WAVEFORMATEX wfx; //struct for format info
MMRESULT result; // for waveOut return values
LPSTR block;
DWORD blockSize;
// first let's set up the wfx format struct
wfx.nSamplesPerSec = 44100; // rate of the sample
wfx.wBitsPerSample = 16; //sample size
wfx.nChannels = 2; // 2 channels = stereo
wfx.cbSize = 0; // no extra info
wfx.wFormatTag = WAVE_FORMAT_PCM; //PCM format
wfx.nBlockAlign = (wfx.wBitsPerSample >> 3) * wfx.nChannels;
wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
// then let's open the device
if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL) != MMSYSERR_NOERROR)
{
fprintf(stderr, "unable to open Wave Mapper device.\n");
Sleep(1000);
ExitProcess(1);
}
// if no errors then close it
printf("The Wave Mapper device was opened successfully!\n");
//load and play file
if((block = loadAudioBlock("ding.raw", &blockSize)) == NULL)
{
fprintf(stderr, "Unable to load file\n");
Sleep(1000);
ExitProcess(1);
}
writeAudioBlock(hWaveOut, block, blockSize);
Sleep(1000);
waveOutClose(hWaveOut);
return 0;
}
Everytime I run the program I get the: "Unable to load file" output. I've got the "ding.raw" file in the same directory as my exe. I've also tried doing the full path as "C://path" and "C:/path" but then the compiler just gives me more errors about being unable to load a pdb file.
Any ideas? I'm using the Visual Studio 2012 Professional IDE and compiler.
Instead of using the standard char you should be using e.g. _TCHAR and LPCTSTR everywhere. This will make all string and string pointers you pass around be correct.
Look at the argv argument to _tmain and you will see that it uses _TCHAR instead of char. This is because Windows support both normal characters and Unicode characters depending on a couple of macros. See e.g. here for some more information.
So to solve what is likely your problem (since you don't get the actual error code, see my comment about GetLastError) you should change the function like this:
void *loadAudioBlock(LPCTSTR filename, DWORD* blockSize)
{
// ...
if((hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
return NULL;
// ...
}
And call it like this:
// ...
void *block;
if((block = loadAudioBlock(_T("C:\\path\\ding.raw"), &blockSize)) == NULL)
{
fprintf(stderr, "unable to open Wave Mapper device, error code %ld.\n", GetLastError());
Sleep(1000);
ExitProcess(1);
}
// ...
As you can see I also changed the return type, as the file is binary and won't have any readable text.
LPSTR loadAudioBlock(const char* filename, DWORD* blockSize)
{
if((hFile = CreateFile(CA2T(filename), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
return NULL;
}
See ATL conversion macros: http://msdn.microsoft.com/en-us/library/87zae4a3%28v=vs.80%29.aspx Just casting const char* LPCWSTR doesn't work.

Programmatically Installing Fonts

How could I programmatically install a font on the Mac platform (Snow Leopard)? What steps would I need to follow? I would like for the user to input a font file, then my software installs it.
Fonts belong in ~user/Library/Fonts/ for a single user or /Library/Fonts/ to be accessible to all users. You need to get permission in order to write to /Library/Fonts/, although there is an API for that which makes it relatively easy. (I have the code somewhere and can look it up if no one else knows offhand.)
As requested, here are some API docs:
http://developer.apple.com/mac/library/documentation/Security/Reference/authorization_ref/Reference/reference.html
This is old code I have that did the update under Carbon (hence the pascal strings). It was based on sample code which is probably somewhere in the above URL. I haven't looked into doing this under Cocoa, and this is a edited version of the code (still a bit messy), so YMMV.
int main()
{
OSStatus myStatus = -1;
char path[1024];
char myToolPath[2048];
getUpdateAppPath(myToolPath);
getFilePath(path);
if (path[0] != 0)
{
char temp[2048];
FILE *f;
printf("Attempting to open \'%s\'\n", path);
f = fopen(path, "w+");
if (f != 0) // we seem to have write permission
{
fclose(f);
SInt16 res;
sprintf(temp, "\'%s\' \'%s\'", myToolPath, path);
system(temp);
StandardAlert(kAlertNoteAlert, "\pUpdate Complete", "\pSuccessfully updated.", 0, &res);
return 0;
}
AuthorizationFlags myFlags = kAuthorizationFlagDefaults;
AuthorizationRef myAuthorizationRef;
myStatus = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
myFlags, &myAuthorizationRef);
if (myStatus != errAuthorizationSuccess)
{
SInt16 res;
StandardAlert(kAlertNoteAlert, "\pAuthorization Error", "\pCould not authorize application to update.", 0, &res);
return myStatus;
}
AuthorizationItem myItems = {kAuthorizationRightExecute, 0, NULL, 0};
AuthorizationRights myRights = {1, &myItems};
myFlags = kAuthorizationFlagDefaults |
kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagPreAuthorize |
kAuthorizationFlagExtendRights;
myStatus = AuthorizationCopyRights (myAuthorizationRef, &myRights, NULL, myFlags, NULL );
if (myStatus != errAuthorizationSuccess)
break;
char *myArguments[] = { path, NULL };
FILE *myCommunicationsPipe = NULL;
char myReadBuffer[128];
myFlags = kAuthorizationFlagDefaults;
myStatus = AuthorizationExecuteWithPrivileges(myAuthorizationRef, myToolPath, myFlags, myArguments,
&myCommunicationsPipe);
if (myStatus == errAuthorizationSuccess)
for(;;)
{
int bytesRead = read (fileno (myCommunicationsPipe),
myReadBuffer, sizeof (myReadBuffer));
if (bytesRead < 1) break;
write (fileno (stdout), myReadBuffer, bytesRead);
}
AuthorizationFree (myAuthorizationRef, kAuthorizationFlagDefaults); // 17
}
if (myStatus)
{
printf("Status: %ld\n", myStatus);
SInt16 res;
StandardAlert(kAlertNoteAlert, "\pUpdater Error", "\pMay not have updated properly.", 0, &res);
}
else {
SInt16 res;
StandardAlert(kAlertNoteAlert, "\pUpdate Complete", "\pSuccessfully updated.", 0, &res);
}
return myStatus;
}