I have been trying to write a file in path returned by SHGetFolderPath . But as File Is created, it has been given Write Protected. Following is my Code:
#include <Windows.h>
#include <Shlobj.h>
#include <iostream>
#include <Shlwapi.h>
int main()
{
HANDLE hfile;
TCHAR szPath[MAX_PATH];
char dataBuffer[] = "Some data to write here";
DWORD dwBytesWritten = 0;
if(SUCCEEDED(SHGetFolderPath(NULL,CSIDL_COMMON_APPDATA,NULL,0, szPath)))
{
std::cout << szPath << std::endl;
PathAppend(szPath,TEXT("lpa"));
std::cout << szPath << std::endl;
PathAppend(szPath,TEXT("config"));
std::cout << szPath << std::endl;
CreateDirectory(szPath, NULL);
PathAppend(szPath, TEXT("lpa.config"));
std::cout << szPath << std::endl;
hfile = CreateFile(szPath,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
/*WriteFile(hfile,dataBuffer,(DWORD)strlen(dataBuffer),&dwBytesWritten,NULL);
std::cout << szPath <<std::endl;*/
}
}
The code creates a file in C:\ProgramData\lpa\config\lpa.config but editing the file pops up dialog saying WriteProtection. What am I doing wrong here?
Yes, When you run VS instance with Admin privileges, special permissions are assigned to the created file. Either run as the program as Non-Admin or use SECURITY_DESCRIPTOR so that other user can access the file.
Creating a Security Descriptor for a New Object in C++
the example in the link shows how a registry key is created, you can put CreateFile() instead.
I solved the issue by using CSIDL_LOCAL_APPDATA instead of CSIDL_COMMON_APPDATA . I have the modified code given as below:
#include <Windows.h>
#include <Shlobj.h>
#include <iostream>
#include <Shlwapi.h>
int main()
{
HANDLE hfile;
TCHAR szPath[MAX_PATH];
char dataBuffer[] = "Some data to write here";
DWORD dwBytesWritten = 0;
if(SUCCEEDED(SHGetFolderPath(NULL,CSIDL_LOCAL_APPDATA,NULL,0, szPath)))
{
std::cout << szPath << std::endl;
PathAppend(szPath,TEXT("lpa"));
if(!CreateDirectory(szPath, NULL))
{
std::cout << "Create directory failed" <<std::endl;
}
std::cout << szPath << std::endl;
PathAppend(szPath,TEXT("config"));
if(!CreateDirectory(szPath, NULL))
{
std::cout << "Create directory failed" <<std::endl;
}
std::cout << szPath << std::endl;
PathAppend(szPath, TEXT("lpa.config"));
std::cout << szPath << std::endl;
hfile = CreateFile(szPath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
WriteFile(hfile,dataBuffer,(DWORD)strlen(dataBuffer),&dwBytesWritten,NULL);
std::cout << szPath <<std::endl;
}
}
Related
I am trying to create a program which copy itself while it is running to new location without keeping the orignal file location . once it is copied I got the file without extension , but how can I overcome this ?
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR szFilepath[MAX_PATH];
TCHAR szFilename[MAX_PATH];
TCHAR szDestpath[MAX_PATH];
/* Get the current executable's full path */
GetModuleFileName(NULL, szFilepath, MAX_PATH);
std::wcout << "filepath: " << szFilepath << std::endl;
/* Extract just the name */
GetFileTitle(szFilepath, szFilename, MAX_PATH);
std::wcout << "filename: " << szFilename << std::endl;
//Set the destination folder path
_tcscpy(szDestpath, L"D:\\");
//Set the destination file path
_tcscat(szDestpath, szFilename);
std::wcout << "dest path: " << szDestpath << std::endl;
// copys the file of your '.exe'
if (!CopyFile(szFilepath, szDestpath, FALSE)) {
std::cout << "couldnt copy the file";
}
else {
std::cout << "copied";
}
return 0;
}
Per the documentation for GetFileTitle():
GetFileTitle returns the string that the system would use to display the file name to the user. The display name includes an extension only if that is the user's preference for displaying file names. This means that the returned string may not accurately identify the file if it is used in calls to file system functions.
You should be using a more suitable function to get the actual filename, such as PathFindFileName():
#include <windows.h>
#include <shlwapi.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR szFilepath[MAX_PATH];
LPWSTR lpszFilename;
WCHAR szDestpath[MAX_PATH];
/* Get the current executable's full path */
GetModuleFileNameW(NULL, szFilepath, MAX_PATH);
std::wcout << L"filepath: " << szFilepath << std::endl;
/* Extract just the name */
lpszFilename = PathFindFileNameW(szFilepath);
std::wcout << L"filename: " << lpszFilename << std::endl;
/* Set the destination folder path and file name */
PathCombineW(szDestpath, L"D:\\", lpszFilename);
std::wcout << L"dest path: " << szDestpath << std::endl;
// copys the file of your '.exe'
if (!CopyFileW(szFilepath, szDestpath, FALSE)) {
std::wcout << L"couldnt copy the file";
}
else {
std::wcout << L"copied";
}
return 0;
}
Or, you could simply parse the filename yourself using normal C++ string operations, eg:
#include <windows.h>
#include <iostream>
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR szFilepath[MAX_PATH];
std::wstring wFilepath;
std::wstring wFilename;
std::wstring wDestpath;
/* Get the current executable's full path */
wFilepath = std::wstring(szFilepath, GetModuleFileNameW(NULL, szFilepath, MAX_PATH));
std::wcout << L"filepath: " << wFilepath << std::endl;
/* Extract just the name */
wFilename = wFilepath.substr(wFilepath.find_last_of(L"\\/")+1);
std::wcout << L"filename: " << wFilename << std::endl;
/* Set the destination folder path and file name */
wDestpath = L"D:\\" + wFilename;
std::wcout << L"dest path: " << wDestpath << std::endl;
// copys the file of your '.exe'
if (!CopyFileW(wFilepath.c_str(), wDestpath.c_str(), FALSE)) {
std::wcout << L"couldnt copy the file";
}
else {
std::wcout << L"copied";
}
return 0;
}
I am trying to display in console a list of running processes and the current time and save them to a text file using the WriteFile and windows.h functions. How to effectively redirect the output stream and "My data..." to a text file without using "freopen" in C ++?
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <chrono>
using namespace std;
int main()
{
char temp;
HANDLE h = CreateFile("process.txt", // name of the file
GENERIC_WRITE, // open for writing
0, // sharing mode, none in this case
0, // use default security descriptor
CREATE_ALWAYS, // overwrite if exists
FILE_ATTRIBUTE_NORMAL,
0);
if (h)
{
std::cout << "CreateFile() succeeded\n";
CloseHandle(h);
}
else
{
std::cerr << "CreateFile() failed:" << GetLastError() << "\n";
}
time_t actualTime = chrono::system_clock::to_time_t(chrono::system_clock::now());
cout << ctime(&actualTime);
cout << "My data..." << endl;
PROCESSENTRY32 proc32;
HANDLE hSnapshot;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
proc32.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hSnapshot, &proc32))
{
cout << proc32.szExeFile << endl;
while(Process32Next(hSnapshot, &proc32))
cout << proc32.szExeFile << endl;
}
WriteFile(HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);
CloseHandle(hSnapshot);
system ("pause >nul");
return 0;
}
Use OPEN_ALWAYS instead of CREATE_ALWAYS and then use SetFilePointer to move the file pointer to the end of file.
i would like to find a way detecting the type of the media in my optical drive (e.g. DVD+R, DVD-R, DVD-RW, CD+R, etc.) using a simple function in C++ on windows.
The function should not require Admin privilege.
EDIT
I implemented the following code:
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <iostream>
#include <sstream>
#include <imapi2.h>
#include <imapi2fs.h>
#include <imapi2error.h>
#include <imapi2fserror.h>
int main(int argc, char *argv[])
{
IDiscFormat2Data* discFormatData = NULL;
HRESULT hr;
CoInitialize ( NULL );
hr = CoCreateInstance( __uuidof(MsftDiscFormat2Data),
NULL,
CLSCTX_ALL,
__uuidof(IDiscFormat2Data),
(void**)&discFormatData);
if ( SUCCEEDED(hr) )
{
IMAPI_MEDIA_PHYSICAL_TYPE mediaType = IMAPI_MEDIA_TYPE_UNKNOWN;
hr = discFormatData->get_CurrentPhysicalMediaType(&mediaType);
if ( SUCCEEDED(hr) )
{
std::cout << "MediaPhysicalType: " << mediaType << std::endl;
}
else
{
std::stringstream str;
str << "get_CurrentPhysicalMediaType() failed with the error: 0x";
str << std::hex << hr << ".";
std::cout << str.str() << std::endl;
}
// Release the interface.
// Tell the COM object that we're done with it.
discFormatData->Release();
}
else
{
std::stringstream str;
str << "CoCreateInstance() failed with the error: 0x" << std::hex << hr;
std::cout << str.str() << std::endl;
}
cin.get();
return 0;
}
at the moment my problem is that i get the following error: E_IMAPI_RECORDER_REQUIRED which means
"The request requires a current disc recorder to be selected."
Assuming i have at least two optical drivers, how can i differ between them?
Any ideas?
On Windows 2000 and later, you can use IOCTL_CDROM_GET_CONFIGURATION with the SCSI_GET_CONFIGURATION_REQUEST_TYPE_CURRENT flag to query an optical device for its current profile, which will tell you which type of disc (CD, DVD+-R/W, HDDVD, BluRay, etc) has been inserted, if any. On earlier versions, you will have to manually send SCSI MMC commands directly to the device to query the same info.
I need to open a certain named pipe so I can fuzz test it, however my test code does not have access to the same data used to generate the name of the named pipe. However I can recognize the name of the pipe and then use that name to open up the pipe for fuzzing.
I used this forum post to start enumerating names of the handles on the system:
http://forum.sysinternals.com/howto-enumerate-handles_topic18892.html
However it seems that won't work with named pipes for some reason.
TL;DR: What API(s) do I need to use to list the names of all named pipes in the current process on Windows?
This will enumerate all named pipes in the system, or at the very least put you a step in the right direction.
This works in MinGW when built with -fpermissive. It should work with similar settings in MSVC.
#ifndef _WIN32_WINNT
// Windows XP
#define _WIN32_WINNT 0x0501
#endif
#include <Windows.h>
#include <Psapi.h>
// mycreatepipeex.c is at http://www.davehart.net/remote/PipeEx.c
// I created a simple header based on that.
#include "mycreatepipeex.h"
#include <iostream>
#include <cstdio>
#include <errno.h>
void EnumeratePipes()
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
#define TARGET_PREFIX "//./pipe/"
const char *target = TARGET_PREFIX "*";
memset(&FindFileData, 0, sizeof(FindFileData));
hFind = FindFirstFileA(target, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
std::cerr << "FindFirstFileA() failed: " << GetLastError() << std::endl;
return;
}
else
{
do
{
std::cout << "Pipe: " << TARGET_PREFIX << FindFileData.cFileName << std::endl;
}
while (FindNextFile(hFind, &FindFileData));
FindClose(hFind);
}
#undef TARGET_PREFIX
return;
}
int main(int argc, char**argv)
{
HANDLE read = INVALID_HANDLE_VALUE;
HANDLE write = INVALID_HANDLE_VALUE;
unsigned char pipe_name[MAX_PATH+1];
BOOL success = MyCreatePipeEx(&read, &write, NULL, 0, 0, 0, pipe_name);
EnumeratePipes();
if ( success == FALSE )
{
std::cerr << "MyCreatePipeEx() failed: " << GetLastError() << std::endl;
return 1;
}
FILE *f = fopen((const char*)pipe_name, "rwb");
if ( f == NULL )
{
std::cerr << "fopen(\"" << pipe_name << "\") failed: " << (int)errno << std::endl;
}
CloseHandle(read);
CloseHandle(write);
return 0;
}
I am having a really hard time with some API calls to the Wininet dll. I am trying to read cookies client side set by IE 9. Here's the code.
#include "stdafx.h"
#include <Windows.h>
#include <WinInet.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
LPTSTR lpData = NULL;
DWORD dwSz = 500;
std::cout << "Hello Chris" << std::endl;
lpData = new TCHAR[dwSz];
std::wcout << "Arg 0: " << argv[1] << std::endl;
bool val = InternetGetCookieEx(argv[1], argv[2], lpData, &dwSz, INTERNET_COOKIE_THIRD_PARTY | INTERNET_FLAG_RESTRICTED_ZONE, NULL);
if (!val)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
std::cout << "Insufficent Buffer size" << std::endl;
lpData = new TCHAR[dwSz];
val = InternetGetCookieEx(argv[1], argv[2], lpData, &dwSz, INTERNET_COOKIE_THIRD_PARTY | INTERNET_FLAG_RESTRICTED_ZONE, NULL);
if (val)
{
std::cout << "Cookie Data: " << lpData << std::endl;
}
else
{
std::cout << "ERROR Code: " << GetLastError() << std::endl;
}
}
else
{
int err = GetLastError();
std::cout << "ERROR Code: " << err << std::endl;
}
}
else
{
std::cout << "Cookie Data: " << lpData << std::endl;
}
//}
return 0;
}
The problem that I am having is that when I call InternetGetCookeEx I always return false and get an error code of 259, which means no more data available. When you consult the API essentially what that means is that it couldn't find my cookie.
Because I am using IE 9 the names for files that the cookie is being stored in are obviously mangled , which is why I am trying to read my cookie data that way.
I have removed the company name to protect the company. Essentially what I am trying to do is. Find the lUsrCtxPersist cookie value. Therefore I am calling the code as such CookieReader.ext http://[CompanyDomain].com lUsrCtxPersist.
However I always get a false and an error code of 259. Any light you might be able to shed on this would be greatly appreciated.
http://msdn.microsoft.com/en-us/library/ms537312%28v=vs.85%29.aspx
Try to use IEGetProtectedModeCookie
Assuming the cookie name is correct, then try removing the INTERNET_COOKIE_THIRD_PARTY and/or INTERNET_FLAG_RESTRICTED_ZONE flags and see what happens. Or try calling InternetGetCookie() instead, which has no such flags available.
On a separate note, when InternetGetCookieEx() returns ERROR_INSUFFICIENT_BUFFER, you are leaking memory. You need to delete[] your existing buffer before then calling new[] to allocate a new buffer.