When i am trying to add resources to another file at run time, some of the earlier resources are getting deleted. Please find the source code below:
void CResourceIncludeSampleDlg::OnBnClickedButton1()
{
CString strInputFile = _T("C:\\SampleData\\FileToInsert.zip"); // This File is 100 MB
HANDLE hFile = CreateFile(strInputFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD FileSize = GetFileSize(hFile, NULL);
BYTE *pBuffer = new BYTE[FileSize];
DWORD dwBytesRead;
ReadFile(hFile, pBuffer, FileSize, &dwBytesRead, NULL);
for (int iIndex = 1; iIndex <= 4; iIndex++)
{
InsertResource(FileSize, iIndex, pBuffer);
}
CloseHandle(hFile);
}
void CResourceIncludeSampleDlg::InsertResource(DWORD FileSize, int iIndex, BYTE *pBuffer)
{
CString strOutputFile = _T("C:\\SampleData\\ResourceIncludeSample_Source.exe");
int iResourceID = 300 + iIndex;
HANDLE hResource = BeginUpdateResource(strOutputFile, FALSE);
if (INVALID_HANDLE_VALUE != hResource)
{
if (UpdateResource(hResource, _T("VIDEOBIN"), MAKEINTRESOURCE(iResourceID), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPVOID)pBuffer, FileSize) == TRUE)
{
EndUpdateResource(hResource, FALSE);
}
}
}
After completion of the execution, i am expecting output as 301, 302, 303 and 304 added under "VIDEOBIN" category. But only 2 (sometimes 3) resources are present. One resource is always deleted.
Could you please let me know what could be wrong or any fix for the same ?
Any help or sample source code is greatly appreciated.
Thanks and Regards,
YKK Reddy
You need delete[] pBuffer after closing the file. It should be RT_RCDATA instead of _T("VIDEOBIN") although custom resource name may not be the cause of this particular problem.
Related
I'm trying to upload a file size of 230GB into azure block blob with the following code
private void uploadFile(FileObject srcFile, FileObject destFile) throws Exception {
try {
BlobClient destBlobClient = blobContainerClient.getBlobClient("destFilename");
long blockSize = 4 * 1024 * 1024 // 4 MB
ParallelTransferOptions opts = new ParallelTransferOptions()
.setBlockSizeLong(blockSize)
.setMaxConcurrency(5);
BlobRequestConditions requestConditions = new BlobRequestConditions();
try (BlobOutputStream bos = destBlobClient.getBlockBlobClient().getBlobOutputStream(
opts, null, null, null, requestConditions);
InputStream is = srcFile.getContent().getInputStream()) {
byte[] buffer = new byte[(int) blockSize];
int i = 0;
for (int len; (len = is.read(buffer)) != -1; ) {
bos.write(buffer, 0, len);
}
}
}
finally {
destFile.close();
srcFile.close();
}
}
Since,I am explicitly setting block size 4MB for each write operation I'm in a assumption that each write block is considered as single block in azure. But which is not the case.
For the above example 230GB file the write operation was executed 58880 times and the file got uploaded successfully.
Can someone please explain me more about how blocks are splits internally in azure and let help me to understand better.
Thanks in advance
I am creating Smart.log file using following code :
void S_SetLogFileName()
{
char HomeDir[MAX_PATH];
if (strlen(LogFileName) == 0)
{
TCHAR AppDataFolderPath[MAX_PATH];
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, AppDataFolderPath)))
{
sprintf(AppDataFolderPath, "%s\\Netcom\\Logs", AppDataFolderPath);
if (CreateDirectory(AppDataFolderPath, NULL) || ERROR_ALREADY_EXISTS == GetLastError())
sprintf(LogFileName,"%s\\Smart.log",AppDataFolderPath);
else
goto DEFAULTVALUE;
}
else
{
DEFAULTVALUE:
if (S_GetHomeDir(HomeDir,sizeof(HomeDir)))
sprintf(LogFileName,"%s\\Bin\\Smart.log",HomeDir);
else
strcpy(LogFileName,"Smart.log");
}
}
}
and opening and modifying it as follows:
void LogMe(char *FileName,char *s, BOOL PrintTimeStamp)
{
FILE *stream;
char buff[2048] = "";
char date[256];
char time[256];
SYSTEMTIME SystemTime;
if(PrintTimeStamp)
{
GetLocalTime(&SystemTime);
GetDateFormat(LOCALE_USER_DEFAULT,0,&SystemTime,"MM':'dd':'yyyy",date,sizeof(date));
GetTimeFormat(LOCALE_USER_DEFAULT,0,&SystemTime,"HH':'mm':'ss",time,sizeof(time));
sprintf(buff,"[%d - %s %s]", GetCurrentThreadId(),date,time);
}
stream = fopen( FileName, "a" );
fprintf( stream, "%s %s\n", buff, s );
fclose( stream );
}
Here's the problem:
UserA runs the program first, it creates \ProgramData\Netcom\Smart.log using S_SetLogFileName()
UserB runs the program next, it tries to append/ modify to Smart.log and gets access denied.
What should i need to change in my code to allow all users to access Smart.log file ?
This is solution, I am looking for, Hope useful for some one.
refer from :
void SetFilePermission(LPCTSTR FileName)
{
PSID pEveryoneSID = NULL;
PACL pACL = NULL;
EXPLICIT_ACCESS ea[1];
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
// Create a well-known SID for the Everyone group.
AllocateAndInitializeSid(&SIDAuthWorld, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&pEveryoneSID);
// Initialize an EXPLICIT_ACCESS structure for an ACE.
ZeroMemory(&ea, 1 * sizeof(EXPLICIT_ACCESS));
ea[0].grfAccessPermissions = 0xFFFFFFFF;
ea[0].grfAccessMode = GRANT_ACCESS;
ea[0].grfInheritance = NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR)pEveryoneSID;
// Create a new ACL that contains the new ACEs.
SetEntriesInAcl(1, ea, NULL, &pACL);
// Initialize a security descriptor.
PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH);
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
// Add the ACL to the security descriptor.
SetSecurityDescriptorDacl(pSD,
TRUE, // bDaclPresent flag
pACL,
FALSE); // not a default DACL
//Change the security attributes
SetFileSecurity(FileName, DACL_SECURITY_INFORMATION, pSD);
if (pEveryoneSID)
FreeSid(pEveryoneSID);
if (pACL)
LocalFree(pACL);
if (pSD)
LocalFree(pSD);
}
I am running the Portable Device API to automatically get Photos from a connected Smart Phone. I have it all transferring correctly. The code that i use is that Standard DownloadFile() routine:
public PortableDownloadInfo DownloadFile(PortableDeviceFile file, string saveToPath)
{
IPortableDeviceContent content;
_device.Content(out content);
IPortableDeviceResources resources;
content.Transfer(out resources);
PortableDeviceApiLib.IStream wpdStream;
uint optimalTransferSize = 0;
var property = new _tagpropertykey
{
fmtid = new Guid(0xE81E79BE, 0x34F0, 0x41BF, 0xB5, 0x3F, 0xF1, 0xA0, 0x6A, 0xE8, 0x78, 0x42),
pid = 0
};
resources.GetStream(file.Id, ref property, 0, ref optimalTransferSize, out wpdStream);
System.Runtime.InteropServices.ComTypes.IStream sourceStream =
// ReSharper disable once SuspiciousTypeConversion.Global
(System.Runtime.InteropServices.ComTypes.IStream)wpdStream;
var filename = Path.GetFileName(file.Name);
if (string.IsNullOrEmpty(filename))
return null;
FileStream targetStream = new FileStream(Path.Combine(saveToPath, filename),
FileMode.Create, FileAccess.Write);
try
{
unsafe
{
var buffer = new byte[1024];
int bytesRead;
do
{
sourceStream.Read(buffer, 1024, new IntPtr(&bytesRead));
targetStream.Write(buffer, 0, 1024);
} while (bytesRead > 0);
targetStream.Close();
}
}
finally
{
Marshal.ReleaseComObject(sourceStream);
Marshal.ReleaseComObject(wpdStream);
}
return pdi;
}
}
There are two problems with this standard code:
1) - when the images are saves to the windows machine, there is no EXIF information. this information is what i need. how do i preserve it?
2) the saved files are very bloated. for example, the source jpeg is 1,045,807 bytes, whilst the downloaded file is 3,942,840 bytes!. it is similar to all of the other files. I would of thought that the some inside the unsafe{} section would output it byte for byte? Is there a better way to transfer the data? (a safe way?)
Sorry about this. it works fine.. it is something else that is causing these issues
The code is below and it is part of a thread. pFileChange->m_hDirectory is of type HANDLE and pFileChange->m_eventFileChange if of type CEvent. CreateFile and ReadDirectoryChangesW return with a success. I am not able to figure out why i am getting an invalid handle status, please help!
UINT CFileChange::FileMontiorThread(LPVOID pArgs)
{
CFileChange* pFileChange = NULL;
pFileChange = (CFileChange*)pArgs;
pFileChange = (CFileChange*)pArgs;
CString str = pFileChange->m_strDirectory;
LPSTR strDirectory;
strDirectory = str.GetBuffer(str.GetLength());
PathRemoveFileSpec(strDirectory);
DWORD dwBytes = 0;
vector<BYTE> m_Buffer;
BOOL m_bChildren;
OVERLAPPED m_Overlapped;
HANDLE arrHandles[2] = { pFileChange->m_hDirectory, pFileChange->m_eventFileChange };
::ZeroMemory(&m_Overlapped, sizeof(OVERLAPPED));
DWORD dwBufferSize = 16384;
m_Buffer.resize(dwBufferSize);
m_bChildren = false;
pFileChange->m_hDirectory = ::CreateFile(
(LPCSTR)(LPCTSTR)strDirectory,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS
| FILE_FLAG_OVERLAPPED,
NULL);
if (pFileChange->m_hDirectory == INVALID_HANDLE_VALUE)
{
return false;
}
BOOL success = ::ReadDirectoryChangesW(
pFileChange->m_hDirectory, // handle to directory
&m_Buffer[0], // read results buffer
m_Buffer.size(), // length of buffer
m_bChildren, // monitoring option
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_FILE_NAME, // filter conditions
&dwBytes, // bytes returned
&m_Overlapped, // overlapped buffer
NULL); // no completion routine
DWORD dwWaitStatus;
while (!pFileChange->m_bKillThread)
{
dwWaitStatus = WaitForMultipleObjects(2, arrHandles, FALSE, INFINITE);
Switch(dwWaitStatus)
{
case WAIT_FAILED:
{
ULONG rc = 0;
rc = ::GetLastError();
LPVOID lpMsgBuf = NULL;
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
rc,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL);
CString strErrMsg;
strErrMsg.Format(_T("%s, %s, Reason:%s"), "", "", (LPTSTR)lpMsgBuf);
break;
}
}
}
return 0;
}
Note that, as it specifies in the documentation, you can't wait on any type of handle.
Waiting on a directory handle isn't going to do what you think it should. Read this related question and its answers for more information and background reading.
As it seems you're trying to create a folder monitor, perhaps read this blog post for the correct way to use ReadDirectoryChangesW.
The answer was provided by Hans Passant in a comment:
You copy the handles into arrHandles too soon, before they are created. That cannot work of course.
I'm trying to fetch contents of an URL on a WM 6.5 not so uber gizmo, using VC++ 2008
CString http_request(CString params){
CInternetSession session(_T("My Session")); // add device identifier here?
CHttpConnection* pServer = NULL;
CHttpFile* pFile = NULL;
CString szHeaders( _T("Content-Type: application/x-www-form-urlencoded;Accept: text/xml, text/plain, text/html, text/htm\r\nHost: www.mydomain.com\r\n\r\n"));
CString strObject("");
CString out;
DWORD dwRet;
char *szBuff = new char[1023];
try
{
CString strServerName("www.mydomain.com");
INTERNET_PORT nPort(80);
pServer = session.GetHttpConnection(strServerName, nPort);
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject);
pFile->AddRequestHeaders(szHeaders);
pFile->SendRequest(LPCTSTR(params),params.GetLength());
pFile->QueryInfoStatusCode(dwRet);
if (dwRet == HTTP_STATUS_OK)
{
UINT nRead = pFile->Read(szBuff, 1023);
while (nRead > 0)
{
//read file...
out = CString(szBuff);
}
}
delete pFile;
delete pServer;
}
catch (CInternetException* pEx)
{
//catch errors from WinInet
out = CString("Something went wrong.");
}
session.Close();
return out;
}
I do see the request coming in but the URI does not get passed, the server throws a 500 or 404 because of this.
I've tried passing params as "GET /blah.txt HTTP/1.0" and also "/blah.txt", no luck, would like to keep testing various input parameters but the device hangs for some reason...
Any pointers would be greatly appreciated!
TIA
Later edit: Solution:
Here's how I got it to work, full code snippet in case anyone wants a copy paste solution (yeah these come in handy)
CString http_request(CString server, CString uri){
CInternetSession session(_T("My Session")); // add device identifier here? IMEI ftw
CHttpConnection* pServer = NULL;
CHttpFile* pFile = NULL;
CString szHeaders( _T("Content-Type: application/x-www-form-urlencoded;Accept: text/xml, text/plain, text/html, text/htm\r\nHost: www.domain.com\r\n\r\n")); // maybe pass as param?
CString strObject(uri);
CString out;
DWORD dwRet;
CString params;
char *szBuff = new char[1023];
try
{
CString strServerName(server);
INTERNET_PORT nPort(80);
pServer = session.GetHttpConnection(strServerName, nPort);
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject);
pFile->AddRequestHeaders(szHeaders);
pFile->SendRequest(szHeaders, szHeaders.GetLength(),¶ms, params.GetLength());
pFile->QueryInfoStatusCode(dwRet);
if (dwRet == HTTP_STATUS_OK)
{
UINT nRead = pFile->Read(szBuff, 1023);
//while (nRead > 0)
//{
//read, for more data you might want to uncomment the while and append to a var. I only needed a few bytes actually.
out = CString(szBuff);
//}
} else {
out = CString("Communication error!");
}
delete pFile;
delete pServer;
}
catch (CInternetException* pEx)
{
//catch errors from WinInet
out = CString("Network error!"); // stupid a$$ cpp the code to handle this would be longer than my ****
}
session.Close();
pServer->Close();
return out;
}
your strObject is empty. Shouldn't this be where you put "blah.txt"?
also, you should delete[] szBuf;
and you're calling pServer->Close() after you've deleted pServer which will probably cause your app to except.