How to open file with fopen() in UWP c++? - c++

How can I open a file in UWP application?
My application will have additional files (e.g. Text file)
I want my program to be able to access this file. So how can I do it?

1.) Make sure that the file that you are trying to open is placed in Application local folder(Folder name "LocalState")
Use the below code to find the local folder path.
using namespace Windows::Storage;
using namespace Streams;
textBlock1->Text = ApplicationData::Current->LocalFolder->Path;
This will display local folder path in text block name textBlock1.
2.) To open the file name "Sample.txt"
using namespace Windows::Storage;
using namespace Streams;
String^ localfolder = ApplicationData::Current->LocalFolder->Path;
std::wstring basePath(localfolder->Data());
std::wstring fileName(L"\\Sample.txt");
basePath = basePath + fileName;
const wchar_t* fullpath = basePath.c_str();
size_t size = wcslen(fullpath) * 2 + 2;
char * StartPoint = new char[size];
size_t c_size;
wcstombs_s(&c_size, StartPoint, size, fullpath, size);
FILE *fp_testFile = NULL;
errno_t err;
err = fopen_s(&fp_testFile, StartPoint, "rb");
if (err == 0)
{
OutputDebugStringW(L"opened");
}
else
{
OutputDebugStringW(L"open failed");
}
The string conversion part is really confusing for me.
I also don't know how not to manually place the file in the local folder.
I tried added the file under Solution explorer -> Assets. But the file is not included to the local folder after deployed

Related

fopen / ofstream::open fail when creating a BMP file

Years ago I created a C++ function using FILE to create bitmap files. Recently (not sure when or why) this code is now failing when opening the file. The problem is with the open call ...
file_ptr = fopen("ScreenShots/Screenshot1.bmp", "wb");
Currently this results in an error 13, permission denied error. Change the filename extension to something else and the fopen works fine. For example,
file_ptr = fopen("ScreenShots/Screenshot1.bm2", "wb");
The file saves correctly and when changing the extension back to BMP I can display the file correctly in Paintshop.
Did a quick check using ofstream and same problem.
Any ideas why I get a permission denied error when trying to open BMP files to write data? For information I am using Visual Studio Community 2017 on Windows 10.
To give the complete section of code ...
BITMAPFILEHEADER bitmap_header;
BITMAPINFOHEADER bitmap_info;
FILE *file_ptr;
unsigned int count;
unsigned char tempRGB;
char filename[256];
bool finished;
// CREATE A UNIQUE FILENAME
count = 1;
finished = false;
do
{
// CREATE NAME
sprintf(filename, "ScreenShots/Screenshot%d.bmp", count);
// CHECK IF FILE EXISTS
errno = 0;
file_ptr = fopen(filename, "rb");
if (file_ptr)
{
// FILE EXISTS
fclose(file_ptr);
count = count + 1;
}
else
{
// UNIQUE FILENAME
file_ptr = fopen(filename, "wb");
if (file_ptr == NULL)
{
// UNABLE TO OPEN FOR WRITING - GIVE UP
// (USING OWN LOGGING CLASS)
jalog.log("\nERROR on Screenshot >");
jalog.log(filename);
jalog.log("< >");
jalog.log((short)errno);
return;
}
finished = true;
}
}
while (finished == false);
I've managed to find the issue ... Avast antivirus. I noticed that trying to do an open action for a BMP file took a few seconds while opening any other file type (successfully or unsuccessfully) was instantaneous. As something similar happens when running new programs I tried disabling all the Avast shields and I could successfully create a BMP file using the existing code.
For my own personal use I can whitelist my own programs, but annoying if I get to distributing the program to other people.
Thanks for the help ... and sorry for raising a C++ issue that in the end had nothing to do with C++!

How to set password to zip file with libZip

I'm using libZip in my project,
I success to create zip file output, but I'm having difficulty to set a password to a zip file.
I'm calling the zip_set_default_password fucntion and I'm getting the OK response, but when I'm trying to extract it didn't ask for a password.
Code sample:
int CompressWithPassword(const char * psFileContent, int iFileSize, const char * pcPassword)
{
zip_source *psZipSource = NULL;
zip_int64_t iIndex = 0;
int iError = EOK;
const char * pcZipOutputPath = "/home/user/Documents/myzip.zip";
// Open zip file.
m_psZip =
zip_open(pcZipOutputPath,
ZIP_CREATE /*Create the archive if it does not exist*/,
&iError);
// Zip opend ?
if(iError != ZIP_ER_OK)
{
Close();
return iError;
}
// Generate zip source content.
psZipSource =
zip_source_buffer(m_psZip,
psFileContent,
iFileSize,
0);
// Valid zip source ?
if(psZipSource == NULL)
{
Close();
iError = -1;
return iError;
}
iIndex =
zip_file_add(m_psZip,
pcZipOutputPath,
psZipSource, ZIP_FL_OVERWRITE);
if(iIndex < 0)
{
Close();
return iIndex;
}
// Create password
int iRetPassword =
zip_set_default_password(m_psZip, pcPassword);
// password set ?
if (iRetPassword == -1)
{
Close();
return iRetPassword;
}
// Close zip file.
Close();
return iError;
}
When I'm calling this function, I'm getting OK and the zip file is created, What I'm missing here?
LibZip version 1.1.3-1, OS: fedora 25
Thanks.
I saw that has a lot of people searching by this question, then i'll make an example of zip_file_set_encryption, the method basically ask for zip archive, file index,encryption method and the password:
int main(){
int errCode = 0;
zip *z = zip_open("package.zip",ZIP_CREATE,&errCode);
zip_source_t *source;
char buffer[] = "Hello world!";
source = zip_source_buffer(z,buffer,strlen(buffer),0);
zip_file_add(z,"example.txt",source,0);
/* Available encryption methods:
ZIP_EM_AES_128
ZIP_EM_AES_192
ZIP_EM_AES_256
*/
zip_file_set_encryption(z,/* Index of the file */ 0,/* Encryption method */ ZIP_EM_AES_256,/* Password to encrypt file */ "myPassword");
zip_close(z);
};
then when i use 7-zip to open the zip file created by my program:
7z e package.zip
It just prompt the password to me, if you type the correct then the files in your workspace will be filled with the content:
Enter password (will not be echoed):
with the libzip is possible set file password by name, but with a little process before:
int main(){
int errCode = 0;
zip *z = zip_open("package.zip",ZIP_CREATE,&errCode);
zip_source_t *source;
char buffer[] = "Hello world!";
source = zip_source_buffer(z,buffer,strlen(buffer),0);
zip_file_add(z,"example.txt",source,0);
source = zip_source_buffer(z,buffer,strlen(buffer),0);
zip_file_add(z,"example2.txt",source,0);
// Create struct of file stat
struct zip_stat st;
// Fill the struct with the file name that you want
zip_stat(z,"example2.txt",0,&st);
// Set the password to the file using index that had got by name
/* Available encryption methods:
ZIP_EM_AES_128
ZIP_EM_AES_192
ZIP_EM_AES_256
*/
zip_file_set_encryption(z,/* Index of file */ st.index, /* encryption method */ ZIP_EM_AES_256, /* password */"myPassword");
zip_close(z);
};
I'm creating an wrapper for libzip (not complete yet), an easy way to interact with zip files, the GitHub URL is there: https://github.com/Romulo-Moraes/zipCrafter
Caution, if you set an password to a file, you should set the same password for the whole zip file, cause it can generate an error when you try open with 7-zip, it will try open the first file with your password then will try the same password for the whole zip.
Some unzip program versions will skip your file that was set with password by libzip, i recommend 7-zip
As written in the Libzip Documentation here, 'zip_set_default_password' will "sets the default password used when accessing encrypted files", if you use 'zip_fopen' to open files. otherwise, if you have a different password for single files you can use 'zip_fopen_encrypted' to open them.
If you want to encrypt files you add to an archive you need to use 'zip_file_set_encryption' with (m_psZip, iIndex, method you choose, pcPassword).

PathFileExists returns false when executing application through RemoteApp

My executable built in C++/WinAPI will check for a file placed in the same folder and I use PathFileExists for that. When I run it on a normal computer it finds the file but when I publish the executable on RemoteApp and I run it from Web Access the file is not found. What would I be missing?
// This is the file I want to find (located in the same directory as the EXE)
wstring myfile = L"myfile.conf";
BOOL abspath = FALSE;
// Trying to get the absolute path first
DWORD nBufferLength = MAX_PATH;
wchar_t szCurrentDirectory[MAX_PATH + 1];
if (GetCurrentDirectory(nBufferLength, szCurrentDirectory) == 0) {
szCurrentDirectory[MAX_PATH + 1] = '\0';
} else {
abspath = true;
}
if (abspath) {
// Create the absolute path to the file
myfile = L'\\' + myfile;
myfile = szCurrentDirectory + myfile ;
MessageBox(hWnd, ConvertToUNC(myfile).c_str(), L"Absolute Path", MB_ICONINFORMATION);
} else {
// Get the UNC path
myfile = ConvertToUNC(myfile);
MessageBox(hWnd, myfile.c_str(), L"UNC Path", MB_ICONINFORMATION);
}
// Try to find file
int retval = PathFileExists(myfile.c_str());
if (retval == 1) {
// Do something
} else {
// File not found
}
The ConvertToUNC function is copied from here.
What I see is that, although the executable lies somewhere else, the absolute path is considered to be C:\Windows. I really don't know what is causing this. The server is Windows 2012 R2 and, like I said, applications are run through RemoteApp Web Access. The returned UNC path is just the name of the file (no volume or folder)

c++ read config file parameters using GetPrivateProfileString

I have a win32 console application in C++, Visual Studio 2012. I cannot get the config parameter from the ini file. I tried different possibilities with file path,like placing the .ini file in source folder, write the full path to is, placing in the folder with generated .exe file. The output on the console after executing of the .exe file is 0 or (null) for string in every case. What I am doing wrong? How can I read the parameters?
v1:
LPCTSTR path = L".\\config.ini";
TCHAR protocolChar[32];
int port = GetPrivateProfileString(_T("PORT"), _T("SETTINGS"), _T(""), protocolChar, 32, path);
printf("***%d***\n", port);
v2:
int port = GetPrivateProfileInt(_T("PORT"), _T("SETTINGS"), 0, _T("config.ini"));
config.ini contains:
[SETTINGS]
USER_NUM_MAX = 256 ; Maximum number of users
PORT = 8080;
Oups, under Windows hitting a ini file in not that easy. In both tries (v1 and v2), you look for the file in current directory and then in Windows directory but not in the directory where the executable file is.
The easy way is to put all ini files under Windows directory. If you find cleaner to have the ini file along with the exe one, you have some more work to do :
find the executable file full path
replace the exe end with ini
use that full path to get access to your private ini file
To get the name of the executable file, simply use GetModuleFileName with a NULL HMODULE :
LPCTSTR getExecPath() {
DWORD len = 64;
for (;;) {
LPTSTR fileName = new TCHAR[len];
if (len == ::GetModuleFileName(NULL, fileName, len)) {
delete fileName;
len *= 2;
}
else {
return fileName;
}
}
}
or if you prefere to directly get the ini file name :
LPCTSTR getIniName() {
DWORD len = 4;
for (;;) {
LPTSTR fileName = new TCHAR[len];
if (len == ::GetModuleFileName(NULL, fileName, len)) {
delete fileName;
len *= 2;
}
else {
::lstrcpy(fileName + lstrlen(fileName) - 3, "ini");
return fileName;
}
}
}
and to not forget to delete the file name when done since it is allocated with new ...
Edit per comment :
For reference, the windows directory may depend on windows version. But it can always be retrieved by the API function GetWindowsDirectory. Extract from the reference page :
UINT WINAPI GetWindowsDirectory(
_Out_ LPTSTR lpBuffer,
_In_ UINT uSize
);
Parameters
lpBuffer [out] A pointer to a buffer that receives the path. This path does not end with a backslash unless the Windows directory is the root directory. For example, if the Windows directory is named Windows on drive C, the path of the Windows directory retrieved by this function is C:\Windows. If the system was installed in the root directory of drive C, the path retrieved is C:.
uSize [in] The maximum size of the buffer specified by the lpBuffer parameter, in TCHARs. This value should be set to MAX_PATH.
Return value
If the function succeeds, the return value is the length of the string copied to the buffer, in TCHARs, not including the terminating null character.
If the length is greater than the size of the buffer, the return value is the size of the buffer required to hold the path.
If the function fails, the return value is zero. To get extended error information, call GetLastError. *
I faced this problem when I updated from VS2010 to VS2012.
On VS 2010 I simply called the function with the file name of the .ini-file as argument for lpFileName (see MSDN Documentation).
This was not working for VS 2012 any more, so I changed to go for the complete path like this:
char directoryPath[MAX_PATH];
char readParameter[MAX_STR_LEN];
GetCurrentDirectory( directoryPath, MAX_PATH );
string directoryPathAsString(directoryPath);
directoryPathAsString = directoryPathAsString + "\\" + filename;
GetPrivateProfileString("section","parameter","0",readParameter,MAX_STR_LEN, directoryPathAsString.c_str());

C++ find file on LD_LIBRARY_PATH

In C/C++ Is there an existing way to check to see if a particular file is on a particular path? I imagine syntax that might look like stat() but with additional parms for filename and path.
pathstat( struct stat stResult, const char* filename, const char* path );
using access() function with F_OK flag will check if your file exist. but before that you have to prepare the file path (from filename and path variables ) before pass the file path as input argument in the function access().
In this answer I assume that you use linux as platform
void pathstat( struct stat stResult, const char* filename, const char* path )
char *file;
int path_len;
if (!filename) {
// set error in the stResult
return;
}
path_len = path ? strlen(path) : 0;
file = malloc((strlen(filename) + path_len + 2) * sizeof(char));
// PREPARE THE FILE PATH
if (path && path[0] && path[path_len-1]=='/')
sprintf(file,"%s%s",path,filename);
else if (path && path[0])
sprintf(file,"%s/%s",path,filename);
else
file = strcpy(file,filename);
//NOW CHECK IF THE FILE PATH EXIST WITH ACCESS
if (access(file, F_OK) != -1) {
//file exist
} else {
// file does not exxit
}
free(file);
}