The problem in WinAPI when working with files and directories - c++

I am writing a C++ console program using WinAPI. This program works with files and directories. The program is launched as follows:
app -R -1 "mask"
(for example, "D: \ Work \*").
-R is a recursive directory traversal, -1 - output of information about files (creation date, size, attributes).
Full program code:
LIBSPEC BOOL ConsolePrompt(LPCTSTR, LPTSTR, DWORD, BOOL);
LIBSPEC BOOL PrintStrings(HANDLE, ...);
LIBSPEC BOOL PrintMsg(HANDLE, LPCTSTR);
LIBSPEC VOID ReportError(LPCTSTR, DWORD, BOOL);
BOOL TraverseDirectory(LPCTSTR, DWORD, LPBOOL);
DWORD FileType(LPWIN32_FIND_DATA);
BOOL ProcessItem(LPWIN32_FIND_DATA, DWORD, LPBOOL);
DWORD Options(int argc, LPCTSTR argv[], LPCTSTR OptStr, ...) {
va_list pFlagList;
LPBOOL pFlag;
int iFlag = 0, iArg;
va_start(pFlagList, OptStr);
while ((pFlag = va_arg(pFlagList, LPBOOL)) != NULL && iFlag < (int)_tcslen(OptStr)) {
*pFlag = FALSE;
for (iArg = 1; !(*pFlag) && iArg < argc && argv[iArg][0] == '-'; iArg++)
*pFlag = memchr(argv[iArg], OptStr[iFlag], _tcslen(argv[iArg])) != NULL;
iFlag++;
}
va_end(pFlagList);
for (iArg = 1; iArg < argc && argv[iArg][0] == '-'; iArg++);
return iArg;
}
void pr_err(int code) {
setlocale(LC_ALL, "Russian");
if (code == 3) {
printf("Файл с указанным названием по указанному пути не найден.");
}
else if (code == 5) {
printf("Операция отклонена. Возможны следующие причины: \n");
printf("Копируемый файл защищен от копирования, скрыт или используется операционной системой.\n");
printf("В целевой директории стоит запрет на запись файлов.\n");
}
else if (code == 20) {
printf("Устройство не найдено.\n");
}
else if (code == 123) {
printf("Указано некорректное название для файла или директории. Возможно были использованы запрещенные символы.\n");
}
}
static void PrintAttributes(DWORD Attrs)
{
setlocale(LC_ALL, "Russian");
if (Attrs == INVALID_FILE_ATTRIBUTES)
{
printf(" Ошибка чтения атрибутов\n");
}
else
{
printf(" \nАтрибуты: ");
if (Attrs & FILE_ATTRIBUTE_ARCHIVE)
{
printf("A ");
}
if (Attrs & FILE_ATTRIBUTE_COMPRESSED)
{
printf("C ");
}
if (Attrs & FILE_ATTRIBUTE_DIRECTORY)
{
printf("D ");
}
if (Attrs & FILE_ATTRIBUTE_HIDDEN)
{
printf("H ");
}
if (Attrs & FILE_ATTRIBUTE_READONLY)
{
printf("R ");
}
printf("\n");
}
}
int _tmain(int argc, LPCTSTR argv[]) {
setlocale(LC_ALL, "Russian");
BOOL Flags[MAX_OPTIONS], ok = TRUE;
TCHAR PathName[buffsize + 1], CurrPath[buffsize + 1];
LPCTSTR pFileName;
int i, FileIndex;
FileIndex = Options(argc, argv, _T("R1"), &Flags[0], &Flags[1], &Flags[2], NULL);
GetCurrentDirectory(buffsize, CurrPath);
printf("argc = %d Index = %d\n", argc, FileIndex);
if (argc < FileIndex + 1) {
printf("Поиск в текущей директории:\n (%s)\n", CurrPath);
ok = TraverseDirectory(_T("*"), MAX_OPTIONS, Flags);
}
else {
for (i = FileIndex; i < argc; i++) {
pFileName = argv[i];
/* Нужно из pFileName вытащить сабстринг по разделителю *
FileAddress = ... // тут получение адреса
SetCurrentDirectory(FileAddress);
*/
printf("DIR: %s\n", pFileName);
if (!SetCurrentDirectory(pFileName)) {
printf("Ошибка установки директории %s как текущей...", pFileName);
return 1;
}
else {
ok = TraverseDirectory(pFileName, MAX_OPTIONS, Flags) && ok;
SetCurrentDirectory(CurrPath);
}
}
}
return ok ? 0 : 1;
}
static BOOL TraverseDirectory(LPCTSTR PathName, DWORD NumFlags, LPBOOL Flags) {
HANDLE SearchHandle;
WIN32_FIND_DATA FindData;
BOOL Recursive = Flags[0];
DWORD FType, iPass;
TCHAR CurrPath[buffsize + 1];
GetCurrentDirectory(buffsize, CurrPath);
for (iPass = 1; iPass <= 2; iPass++) {
SearchHandle = FindFirstFile(PathName, &FindData);
if (SearchHandle == INVALID_HANDLE_VALUE) {
pr_err(GetLastError());
return 1;
}
do {
FType = FileType(&FindData);
if (iPass == 1)
ProcessItem(&FindData, MAX_OPTIONS, Flags);
if (FType == TYPE_DIR && iPass == 2 && Recursive) {
_tprintf(_T("%s\\%s:\n"), CurrPath, FindData.cFileName);
if (!SetCurrentDirectory(FindData.cFileName))
{
printf("Ошибка установки %s как текущей директории...", FindData.cFileName);
}
else {
TraverseDirectory(_T("*"), NumFlags, Flags);
SetCurrentDirectory(_T(".."));
}
}
} while (FindNextFile(SearchHandle, &FindData));
FindClose(SearchHandle);
}
return TRUE;
}
static BOOL ProcessItem(LPWIN32_FIND_DATA pFileData, DWORD NumFlags, LPBOOL Flags)
{
const TCHAR FileTypeChar[] = { 'c', 'd' };
DWORD FType = FileType(pFileData);
BOOL Long = Flags[1];
SYSTEMTIME LastWrite;
if (FType != TYPE_FILE && FType != TYPE_DIR)
return FALSE;
_tprintf(_T("\n"));
if (Long) {
_tprintf(_T("%c"), FileTypeChar[FType - 1]);
_tprintf(_T("%10d"), pFileData->nFileSizeLow);
FileTimeToSystemTime(&(pFileData->ftLastWriteTime), &LastWrite);
_tprintf(_T(" %02d/%02d/%04d %02d:%02d:%02d "), LastWrite.wMonth, LastWrite.wDay,
LastWrite.wYear, LastWrite.wHour, LastWrite.wMinute, LastWrite.wSecond);
}
_tprintf(_T("%s"), pFileData->cFileName);
PrintAttributes(GetFileAttributesA(pFileData->cFileName));
return TRUE;
}
static DWORD FileType(LPWIN32_FIND_DATA pFileData) {
BOOL IsDir;
DWORD FType;
FType = TYPE_FILE;
IsDir = (pFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
if (IsDir)
if (lstrcmp(pFileData->cFileName, _T(".")) == 0 ||
lstrcmp(pFileData->cFileName, _T("..")) == 0)
FType = TYPE_DOT;
else
FType = TYPE_DIR;
return FType;
}
The problem is switching to the specified path does not work. How can I solve this problem?

Wildcard characters are not accepted in SetCurrentDirectory.
You should to specify a valid path, like "D:\\work\\".
Then, you should call GetFileAttributes to decide whether to add wildcards after the filename.
TCHAR file[MAX_PATH] = {0};
_stprintf(file, _T("%s\\*"), pFileName);
ok = TraverseDirectory(file, MAX_PATH, Flags) && ok;

Related

Interactive Brokers C++ Error: error: 'min' was not declared in this scope

I am trying to setup the Interactive Brokers API on Ubuntu (18.04). I have installed both the IB Gateway, which is used for communicating with exchanges, as well as other API software for developing trading algorithms in Java, C++, C# and Python. (Which you can find here). The API is written in both Java and C++, and as stated prior it offers support for both. However when attempting to compile an example from their source code there is an error in the EReader.cpp file. I have dealt with several other C++ errors in their code however this one I cannot figure out. Here is the code:
#include "StdAfx.h"
#include "shared_ptr.h"
#include "Contract.h"
#include "EDecoder.h"
#include "EMutex.h"
#include "EReader.h"
#include "EClientSocket.h"
#include "EPosixClientSocketPlatform.h"
#include "EReaderSignal.h"
#include "EMessage.h"
#include "DefaultEWrapper.h"
#define IN_BUF_SIZE_DEFAULT 8192
static DefaultEWrapper defaultWrapper;
EReader::EReader(EClientSocket *clientSocket, EReaderSignal *signal)
: processMsgsDecoder_(clientSocket->EClient::serverVersion(), clientSocket->getWrapper(), clientSocket) {
m_isAlive = true;
m_pClientSocket = clientSocket;
m_pEReaderSignal = signal;
m_needsWriteSelect = false;
m_nMaxBufSize = IN_BUF_SIZE_DEFAULT;
m_buf.reserve(IN_BUF_SIZE_DEFAULT);
}
EReader::~EReader(void) {
m_isAlive = false;
#if defined(IB_WIN32)
WaitForSingleObject(m_hReadThread, INFINITE);
#endif
}
void EReader::checkClient() {
m_needsWriteSelect = !m_pClientSocket->getTransport()-
isOutBufferEmpty();
}
void EReader::start() {
#if defined(IB_POSIX)
pthread_t thread;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create( &thread, &attr, readToQueueThread, this );
pthread_attr_destroy(&attr);
#elif defined(IB_WIN32)
m_hReadThread = CreateThread(0, 0, readToQueueThread, this, 0, 0);
#else
# error "Not implemented on this platform"
#endif
}
#if defined(IB_POSIX)
void * EReader::readToQueueThread(void * lpParam)
#elif defined(IB_WIN32)
DWORD WINAPI EReader::readToQueueThread(LPVOID lpParam)
#else
# error "Not implemented on this platform"
#endif
{
EReader *pThis = reinterpret_cast<EReader *>(lpParam);
pThis->readToQueue();
return 0;
}
void EReader::readToQueue() {
EMessage *msg = 0;
while (m_isAlive) {
if (m_buf.size() == 0 && !processNonBlockingSelect() && m_pClientSocket->isSocketOK())
continue;
if (!putMessageToQueue())
break;
}
m_pClientSocket->handleSocketError();
m_pEReaderSignal->issueSignal(); //letting client know that socket was closed
}
bool EReader::putMessageToQueue() {
EMessage *msg = 0;
if (m_pClientSocket->isSocketOK())
msg = readSingleMsg();
if (msg == 0)
return false;
m_csMsgQueue.Enter();
m_msgQueue.push_back(ibapi::shared_ptr<EMessage>(msg));
m_csMsgQueue.Leave();
m_pEReaderSignal->issueSignal();
return true;
}
bool EReader::processNonBlockingSelect() {
fd_set readSet, writeSet, errorSet;
struct timeval tval;
tval.tv_usec = 100 * 1000; //100 ms
tval.tv_sec = 0;
if( m_pClientSocket->fd() >= 0 ) {
FD_ZERO( &readSet);
errorSet = writeSet = readSet;
FD_SET( m_pClientSocket->fd(), &readSet);
if (m_needsWriteSelect)
FD_SET( m_pClientSocket->fd(), &writeSet);
FD_SET( m_pClientSocket->fd(), &errorSet);
int ret = select( m_pClientSocket->fd() + 1, &readSet, &writeSet, &errorSet, &tval);
if( ret == 0) { // timeout
return false;
}
if( ret < 0) { // error
m_pClientSocket->eDisconnect();
return false;
}
if( m_pClientSocket->fd() < 0)
return false;
if( FD_ISSET( m_pClientSocket->fd(), &errorSet)) {
// error on socket
m_pClientSocket->onError();
}
if( m_pClientSocket->fd() < 0)
return false;
if( FD_ISSET( m_pClientSocket->fd(), &writeSet)) {
// socket is ready for writing
onSend();
}
if( m_pClientSocket->fd() < 0)
return false;
if( FD_ISSET( m_pClientSocket->fd(), &readSet)) {
// socket is ready for reading
onReceive();
}
return true;
}
return false;
}
void EReader::onSend() {
m_pEReaderSignal->issueSignal();
}
void EReader::onReceive() {
int nOffset = m_buf.size();
m_buf.resize(m_nMaxBufSize);
int nRes = m_pClientSocket->receive(m_buf.data() + nOffset, m_buf.size() - nOffset);
if (nRes <= 0)
return;
m_buf.resize(nRes + nOffset);
}
bool EReader::bufferedRead(char *buf, int size) {
while (size > 0) {
while (m_buf.size() < size && m_buf.size() < m_nMaxBufSize)
if (!processNonBlockingSelect() && !m_pClientSocket->isSocketOK())
return false;
int nBytes = (std::min<unsigned int>)(m_nMaxBufSize, size);
std::copy(m_buf.begin(), m_buf.begin() + nBytes, buf);
std::copy(m_buf.begin() + nBytes, m_buf.end(), m_buf.begin());
m_buf.resize(m_buf.size() - nBytes);
size -= nBytes;
buf += nBytes;
}
return true;
}
EMessage * EReader::readSingleMsg() {
if (m_pClientSocket->usingV100Plus()) {
int msgSize;
if (!bufferedRead((char *)&msgSize, sizeof(msgSize)))
return 0;
msgSize = htonl(msgSize);
if (msgSize <= 0 || msgSize > MAX_MSG_LEN)
return 0;
std::vector<char> buf = std::vector<char>(msgSize);
if (!bufferedRead(buf.data(), buf.size()))
return 0;
return new EMessage(buf);
}
else {
const char *pBegin = 0;
const char *pEnd = 0;
int msgSize = 0;
while (msgSize == 0)
{
if (m_buf.size() >= m_nMaxBufSize * 3/4)
m_nMaxBufSize *= 2;
if (!processNonBlockingSelect() && !m_pClientSocket->isSocketOK())
return 0;
pBegin = m_buf.data();
pEnd = pBegin + m_buf.size();
msgSize = EDecoder(m_pClientSocket->EClient::serverVersion(), &defaultWrapper).parseAndProcessMsg(pBegin, pEnd);
}
std::vector<char> msgData(msgSize);
if (!bufferedRead(msgData.data(), msgSize))
return 0;
if (m_buf.size() < IN_BUF_SIZE_DEFAULT && m_buf.capacity() > IN_BUF_SIZE_DEFAULT)
{
m_buf.resize(m_nMaxBufSize = IN_BUF_SIZE_DEFAULT);
m_buf.shrink_to_fit();
}
EMessage * msg = new EMessage(msgData);
return msg;
}
}
ibapi::shared_ptr<EMessage> EReader::getMsg(void) {
m_csMsgQueue.Enter();
if (m_msgQueue.size() == 0) {
m_csMsgQueue.Leave();
return ibapi::shared_ptr<EMessage>();
}
ibapi::shared_ptr<EMessage> msg = m_msgQueue.front();
m_msgQueue.pop_front();
m_csMsgQueue.Leave();
return msg;
}
void EReader::processMsgs(void) {
m_pClientSocket->onSend();
checkClient();
ibapi::shared_ptr<EMessage> msg = getMsg();
if (!msg.get())
return;
const char *pBegin = msg->begin();
while (processMsgsDecoder_.parseAndProcessMsg(pBegin, msg->end()) > 0)
{
msg = getMsg();
if (!msg.get())
break;
pBegin = msg->begin();
}
}
The error I get it is the following:
error: 'min' was not declared in this scope int nBytes =
min(m_nMaxBuffSize, size);
I have had to do other things such as editing other source code and makefiles, I am stuck here. Any insight would be appreciated.
In my version 973 source at that line I have
int nBytes = (std::min<unsigned int>)(m_nMaxBufSize, size);
Make sure you are using the latest version. The problem may be an example of what happens here Why is "using namespace std" considered bad practice?

PortAudio: Pa_StartStream() crashes Game Maker when used in DLL

I want to use PortAudio in Game Maker by using a DLL.
I made the callback function in C++ and used that to calculate the frequency of the incoming sample stream. In the DLL I made a few export functions: one that initiates the stream, one that closes the stream and one that gets the frequency variable generated by the callback.
Now when I called the PortAudioStart() function in Game Maker, the game shut down without any warning/error/message of any kind. I put MessageBox()'es in between the lines of code, to check what was the source of the crash. It showed the first, second and third ones, and then it crashed, not even showing the error MessageBox. So it turned out that Pa_StartStream() caused it.
Now I wonder: why does this crash occur, and how can I fix it?
Note: I tested this DLL by letting a C++ program call it, and in that case it worked totally as planned.
I am using GM8.0 and NetBeans 7.3 with the gcc compiler from Cygwin 4.
The start and end functions (leaving out all includes and definitions of global variables):
#define GMEXPORT extern "C" __declspec (dllexport)
GMEXPORT double __cdecl PortAudioStart() {
err = Pa_Initialize();
if( err != paNoError ) goto error;
MessageBoxA(NULL, "1", "PortAudio DLL", MB_ICONINFORMATION);
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
goto error;
}
inputParameters.channelCount = 1; /* mono input */
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
MessageBoxA(NULL, "2", "PortAudio DLL", MB_ICONINFORMATION);
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL, //&outputParameters
SAMPLE_RATE,
FRAMES_PER_BUFFER,
0,
PaCallback,
NULL );
if( err != paNoError ) goto error;
MessageBoxA(NULL, "3", "PortAudio DLL", MB_ICONINFORMATION);
err = Pa_StartStream( stream );
if( err != paNoError ) goto error;
MessageBoxA(NULL, "4", "PortAudio DLL", MB_ICONINFORMATION);
return 1;
error:
MessageBoxA(NULL, "Apparently it doesn't work!", "PortAudio DLL", MB_ICONINFORMATION);
Pa_Terminate();
return 0;
}
GMEXPORT double __cdecl PortAudioEnd() {
err = Pa_CloseStream( stream );
if( err != paNoError ) goto error;
Pa_Terminate();
return 1;
error:
MessageBoxA(NULL, "Apparently it doesn't work!", "PortAudio DLL", MB_ICONINFORMATION);
Pa_Terminate();
return 0;
}
GMEXPORT double __cdecl getFreq()
{
if (Pa_IsStreamStopped(stream) == 0)
{
return frequency; // this variable is constantly changed in the callback function
}
else
{
return 0;
}
}
void calculateFreq(bool sign)
{
unsigned int j;
bool check;
diffsamp = maxsamp - minsamp;
if (!sign)
{
diffsampmax = max((diffsampmax*.85), (double)diffsamp);
maxsamp = 0;
}
if (sign)
{
diffsampmax = max((diffsampmax*.85), (double)diffsamp);
minsamp = 0;
}
check = ( diffsamp > max(25.0,diffsampmax*.90) );
if (sign == lastsign)
{
check = false;
}
if (check)
{
if (timepassed - peaks[0] < 500)
{
for ( j=numpeaks-1; j>0; j-- )
{
peaks[j] = peaks[j-1];
}
}
else
{
for ( j=0; j<numpeaks; j++ )
{
peaks[j] = 0;
}
}
peaks[0] = timepassed;
double diff = peaks[0]-peaks[numpeaks-1];
double peaktime = diff/(numpeaks-1)*2; //*2 because maxdiff is at +>- and ->+
frequency = 1/((double)peaktime/(double)SAMPLE_RATE);
if (peaks[numpeaks-1] <= 0 || frequency < 20) frequency = 0;
lastsign = sign;
}
}
static int PaCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
const SAMPLE *in = (const SAMPLE*)inputBuffer;
unsigned int i;
unsigned int j;
(void) timeInfo; // Prevent unused variable warnings.
(void) statusFlags;
(void) userData;
SAMPLE samp;
if( inputBuffer == NULL )
{
//nothing happens
}
else
{
for( i=0; i<framesPerBuffer; i++ )
{
timepassed += 1;
samp = *in++;
changed = false;
if (samp > 0)
{
if (!sign)
{
sign = true;
changed = true;
}
maxsamp = max(maxsamp,samp);
}
else
{
if (sign)
{
sign = false;
changed = true;
}
minsamp = min(minsamp,samp);
}
if (changed)
{
calculateFreq(sign);
}
}
}
return paContinue;
}
GML:
//// Script: pa_init()
globalvar _pa_freq,_pa_start,_pa_end;
var dll_name;
dll_name = "c:\Users\<Username>\Documents\NetBeansProjects\GMDLLtest\dist\Debug\Cygwin_4.x-Windows\libGMDLLtest.dll";
_pa_freq = external_define(dll_name, "getFreq", dll_cdecl, ty_real, 0);
_pa_start = external_define(dll_name, "PortAudioStart", dll_cdecl, ty_real, 0);
_pa_end = external_define(dll_name, "PortAudioEnd", dll_cdecl, ty_real, 0);
////--------------------------------------------------------------------------------
//// Script: pa_start()
return external_call(_pa_start);
////--------------------------------------------------------------------------------
//// Script: pa_end()
return external_call(_pa_end);
////--------------------------------------------------------------------------------
//// Script: pa_freq()
return external_call(_pa_freq);
P.S: If anything is unclear, please ask, my knowledge of C++ isn't really outstanding.

can not query values from windows registry

I writing program for the Windows registry and trying to query values from it, but even if I running my own program with the permissions of Administrator, I can not read all parameters and got error code 5 - Access Denied for some values. But at the same time standard regedit could show me that value. What did i doing wrong?
I have a class for the registry RegistryClass
RegistryClass.h:
class RegistryClass
{
HKEY hKey;
public:
int GetCountOfKeys();
bool OpenKey(HKEY key, std::string path);
void EnumKeys(char ** result, int * count);
...
}
RegistryClass.cpp
#include "RegistryClass.h"
...
bool RegistryClass::OpenKey(HKEY key, std::string path)
{
if(RegOpenKeyExA(key,path.c_str(),NULL,KEY_ALL_ACCESS,&hKey) == ERROR_SUCCESS)
{
return true;
}
hKey = NULL;
return false;
}
int RegistryClass::GetCountOfKeys()
{
DWORD count = 0;
char keyName [256];
DWORD len = 255;
while(1)
{
if(RegEnumKeyExA(hKey,count,keyName,&len,NULL,NULL,NULL,NULL) != ERROR_SUCCESS)
break;
count++;
len = 255;
}
return count;
}
void RegistryClass::EnumKeys(char ** result, int * count)
{
if(hKey == NULL)
return;
*count = 0;
DWORD dwIndex = 0; // current key
char keyName [255]; // current key name
DWORD lpcchName = 255; // name length
int error;
do
{
error = RegEnumKeyExA(hKey,dwIndex,keyName,&lpcchName,NULL,NULL,NULL,NULL);
if(error == ERROR_SUCCESS)
{
memcpy(result[(*count)],keyName,lpcchName);
(*count)++;
}
dwIndex++;
lpcchName = 255;
}while(error == ERROR_SUCCESS);
}
in main program i trying to retrive keys
void MainWindow::InitializeFirstState()
{
item_HKEY_CLASSES_ROOT = new QTreeWidgetItem();
item_HKEY_CLASSES_ROOT->setText(0,"HKEY_CLASSES_ROOT");
// and other keys
...
tree->addTopLevelItem(item_HKEY_CLASSES_ROOT);
...
AddInternalKeys(item_HKEY_CLASSES_ROOT,true);
...
}
...
void AddInternalKeys(QTreeWidgetItem * item, bool rec)
{
std::string currentPath = GetFullPathKey(item);
// first key name
std::string keyName = GetParentKeyName(item);
RegistryClass * regC = new RegistryClass();
HKEY key;
if(strcmp(keyName.c_str(),"HKEY_CLASSES_ROOT") == 0)
{
key = HKEY_CLASSES_ROOT;
}
else if(strcmp(keyName.c_str(),"HKEY_CURRENT_USER") == 0)
{
key = HKEY_CURRENT_USER;
}
else if(strcmp(keyName.c_str(),"HKEY_LOCAL_MACHINE") == 0)
{
key = HKEY_LOCAL_MACHINE;
}
else if(strcmp(keyName.c_str(),"HKEY_USERS") == 0)
{
key = HKEY_USERS;
}
else // HKEY_CURRENT_CONFIG
{
key = HKEY_CURRENT_CONFIG;
}
if(regC->OpenKey(key,currentPath) == true)
{
internalLog->print("key opened succesfully\n");
}
else internalLog->print("key was not opened\n");
int count = regC->GetCountOfKeys();
char ** keys = (char **) malloc(sizeof(char *) * count);
for(int i=0;i<count;i++)
{
keys[i] = (char *) malloc(sizeof(char) * 256);
memset(keys[i],0,sizeof(char) * 256);
}
regC->EnumKeys(keys,&count);
regC->CloseKey();
delete regC;
QTreeWidgetItem * newItem;
count--;
while(count >= 0)
{
newItem = new QTreeWidgetItem();
newItem->setText(0,keys[count]);
item->addChild(newItem);
std::string str = keys[count];
AddKeyNames(newItem,str);
free(keys[count]);
if(rec == true)
AddInternalKeys(newItem,false);
count--;
}
free(keys);
}
You are asking for too much access. You are asking for KEY_ALL_ACCESS when all you actually need is KEY_READ. You do not have all-access permission, but you do have read permission.

Using C++ to Merge .reg files

Hey, I am simply trying to merge a .reg file into my registry using a very basic c++ program.
The code is as follows:
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <stdlib.h>
#include <cstdlib>
#include <stdio.h>
#include <windows.h>
using namespace std;
int main()
{
string file = "regedit.exe new.reg";
const char* ctv = file.c_str();
system(ctv);
system("PAUSE");
return 0;
}
I've also tried using these system commands:
ShellExecute(GetDesktopWindow(), "open", "new.reg", NULL, NULL, SW_SHOWNORMAL);
system("reg import new.reg");
system("regedit/s new.reg");
system("new.reg");
but they work no better.
The very interesting thing is that if I go to Start, Run, and type in "regedit.exe new.reg"
The registry WILL update; just not when I run the .exe program.
Any thoughts?
Check out programmatically merge .reg file into win32 registry and additionally import .reg files using win32 or other libraries.
See http://msdn.microsoft.com/en-us/library/ms724889%28VS.85%29.aspx as well which might help.
RegLoadKey Function
Creates a subkey under HKEY_USERS or
HKEY_LOCAL_MACHINE and loads the data
from the specified registry hive into
that subkey.
Applications that back up or restore
system state including system files
and registry hives should use the
Volume Shadow Copy Service instead of
the registry functions.
Just FYI, here is the piece of code from the linked open-source project which handles imports:
void CMainFrame::ImportRegistryFiles(CString csFileName)
{
CStdioFileEx sfRegFile;
TRY
{
sfRegFile.Open(LPCTSTR(csFileName),CFile::modeRead | CFile::typeText);
}
CATCH( CFileException, e )
{
CString csError = _T("");
csError.Format(_T("File could not be opened: %s"), e->m_cause);
MessageBox(csError,_T("Import Error"), MB_OK|MB_ICONERROR);
return;
}
END_CATCH
CNtRegistry ntReg;
ntReg.InitNtRegistry();
//
DWORD dwRegType = 0;
int nDataStarts = 0;
CTokenEx tok;
UCHAR ucData[8192];
CString csValueName = _T("");
CString csFullKey = _T("");
CString csData = _T("");
BOOL bNextLine = FALSE;
BOOL bKeyFound = FALSE;
BOOL bHiddenKey = FALSE;
CString csLine = _T("");
while (sfRegFile.ReadString(csLine)) {
//
if (csLine.Left(3) == _T("[HK")) {
//
csLine.TrimLeft("[");
csLine.TrimRight("]");
CStringArray csaKeyPath;
CString csFullPath = GetRegistryPath(csLine,csaKeyPath);
if (csFullPath.Right(1) == "*") {
// User wants to create a "Hidden" Key ...
bHiddenKey = TRUE;
}
if (!ntReg.KeyExists(csFullPath)) {
//
csFullKey = csaKeyPath.GetAt(0);
for (int n=1; n<csaKeyPath.GetSize(); n++) {
//
csFullKey += _T("\\");
csFullKey += csaKeyPath.GetAt(n);
if (n == (csaKeyPath.GetSize()-1) && csFullKey.Right(1) == "*") {
CString csTmp = csFullKey;
csFullKey = csTmp.Left(csTmp.GetLength()-1);
if (!ntReg.CreateHiddenKey(csFullKey)) {
//
sfRegFile.Close();
return;
}
}
else if (!ntReg.SetKey(csFullKey,TRUE,TRUE)) {
//
sfRegFile.Close();
return;
}
theApp.m_clsTV->TraverseTree(csFullKey);
}
}
else {
//
if (!ntReg.SetKey(csFullPath,TRUE,TRUE)) {
//
sfRegFile.Close();
return;
}
theApp.m_clsTV->TraverseTree(csFullKey);
}
bKeyFound = TRUE;
nDataStarts = 0;
dwRegType = REG_NONE;
csData = _T("");
}
else if ((csLine.Left(2) == _T("#=") ||
csLine.Left(1) == _T("=") ||
csLine.Left(1) == _T("\"")) &&
bKeyFound) {
//
memset(ucData,0,8192);
dwRegType = BreakdownLineInfo(csLine, csValueName, nDataStarts);
#if _MSC_VER >= 1400
csLine.Trim(); // _VC80_
#else
csLine.TrimLeft();
csLine.TrimRight();
#endif
csData = csLine.Mid(nDataStarts);
if (csLine.Right(1) == _T("\\")) {
bNextLine = TRUE;
csData.TrimRight(_T("\\"));
}
else {
// SetValue in Registry
bNextLine = FALSE;
#if _MSC_VER >= 1400
csData.Trim(); // _VC80_
#else
csData.TrimLeft();
csData.TrimRight();
#endif
csData.TrimRight(_T("\""));
BOOL bError = FALSE;
switch (dwRegType) {
case REG_SZ:
bError = ntReg.WriteString(csFullKey,csValueName,csData);
break;
case REG_EXPAND_SZ:
//
{
CString csNewData = _T("");
CString csTmpData = _T("");
int nCtr = 0;
tok.Split(csData,_T(","));
for (int n=0; n<tok.m_csaAddIt.GetSize(); n++) {
int nDec = theApp.Hex2Dec(tok.m_csaAddIt.GetAt(n));
if (nDec != 0) {
csNewData.Format(_T("%c"),nDec);
csNewData += csTmpData;
}
}
bError = ntReg.WriteExpandString(csFullKey,csValueName,csNewData);
}
break;
case REG_DWORD:
case REG_DWORD_BIG_ENDIAN:
{
DWORD dwData = theApp.Hex2Dec(csData);
bError = ntReg.WriteDword(csFullKey,csValueName,dwData);
}
break;
case REG_MULTI_SZ:
//
{
CStringArray csaData;
CString csNewData = _T("");
CString csTmpData = _T("");
int nCtr = 0;
tok.Split(csData,_T(","));
for (int n=0; n<tok.m_csaAddIt.GetSize(); n++) {
int nDec = theApp.Hex2Dec(tok.m_csaAddIt.GetAt(n));
if (nDec != 0) {
csNewData.Format(_T("%c"),nDec);
csNewData += csTmpData;
}
else {
if ((n+1) < tok.m_csaAddIt.GetSize()) {
int nDec2 = theApp.Hex2Dec(tok.m_csaAddIt.GetAt(n+1));
if (nDec2 == 0 && csNewData != _T("")) {
csaData.Add(csNewData);
csNewData = _T("");
}
}
}
}
bError = ntReg.WriteMultiString(csFullKey,csValueName,csaData);
}
break;
case REG_BINARY:
case REG_LINK:
case REG_RESOURCE_LIST:
case REG_FULL_RESOURCE_DESCRIPTOR:
case REG_RESOURCE_REQUIREMENTS_LIST:
case REG_QWORD:
//
{
int nCtr = 0;
tok.Split(csData,_T(","));
for (int n=0; n<tok.m_csaAddIt.GetSize(); n++) {
int nDec = theApp.Hex2Dec(tok.m_csaAddIt.GetAt(n));
ucData[nCtr++] = nDec;
}
UINT uiLength = (UINT)nCtr+1;
bError = ntReg.WriteValue(csFullKey, csValueName, ucData, (ULONG)uiLength, dwRegType);
}
break;
}
}
}
else {
//
memset(ucData,0,8192);
if (bNextLine) {
//
#if _MSC_VER >= 1400
csLine.Trim(); // _VC80_
#else
csLine.TrimLeft();
csLine.TrimRight();
#endif
if (csLine.Right(1) != _T("\\")) {
//
bNextLine = FALSE;
#if _MSC_VER >= 1400
csData.Trim(); // _VC80_
#else
csData.TrimLeft();
csData.TrimRight();
#endif
csData.TrimRight(_T("\""));
BOOL bError = FALSE;
csData += csLine;
// SetValue in Registry
switch (dwRegType) {
case REG_SZ:
bError = ntReg.WriteString(csFullKey,csValueName,csData);
break;
case REG_EXPAND_SZ:
//
{
CString csNewData = _T("");
CString csTmpData = _T("");
int nCtr = 0;
tok.Split(csData,_T(","));
for (int n=0; n<tok.m_csaAddIt.GetSize(); n++) {
int nDec = theApp.Hex2Dec(tok.m_csaAddIt.GetAt(n));
if (nDec != 0) {
csTmpData.Format(_T("%c"),nDec);
csNewData += csTmpData;
}
}
bError = ntReg.WriteExpandString(csFullKey,csValueName,csNewData);
}
break;
case REG_DWORD:
case REG_DWORD_BIG_ENDIAN:
{
DWORD dwData = theApp.Hex2Dec(csData);
bError = ntReg.WriteDword(csFullKey,csValueName,dwData);
}
break;
case REG_MULTI_SZ:
//
{
CStringArray csaData;
CString csNewData = _T("");
CString csTmpData = _T("");
int nCtr = 0;
tok.Split(csData,_T(","));
for (int n=0; n<tok.m_csaAddIt.GetSize(); n++) {
int nDec = theApp.Hex2Dec(tok.m_csaAddIt.GetAt(n));
if (nDec != 0) {
csTmpData.Format(_T("%c"),nDec);
csNewData += csTmpData;
}
else {
if ((n+1) < tok.m_csaAddIt.GetSize()) {
int nDec2 = theApp.Hex2Dec(tok.m_csaAddIt.GetAt(n+1));
if (nDec2 == 0 && csNewData != _T("")) {
csaData.Add(csNewData);
csNewData = _T("");
}
}
}
}
bError = ntReg.WriteMultiString(csFullKey,csValueName,csaData);
}
break;
case REG_BINARY:
case REG_LINK:
case REG_RESOURCE_LIST:
case REG_FULL_RESOURCE_DESCRIPTOR:
case REG_RESOURCE_REQUIREMENTS_LIST:
case REG_QWORD:
//
{
int nCtr = 0;
tok.Split(csData,_T(","));
for (int n=0; n<tok.m_csaAddIt.GetSize(); n++) {
int nDec = theApp.Hex2Dec(tok.m_csaAddIt.GetAt(n));
ucData[nCtr++] = nDec;
}
UINT uiLength = (UINT)nCtr+1;
bError = ntReg.WriteValue(csFullKey, csValueName, ucData, (ULONG)uiLength, dwRegType);
}
break;
}
}
else {
csData += csLine;
#if _MSC_VER >= 1400
csLine.Trim(); // _VC80_
#else
csLine.TrimLeft();
csLine.TrimRight();
#endif
csData.TrimRight(_T("\\"));
}
}
else {
bKeyFound = FALSE;
}
}
}
}

In an MFC application, what's the easiest way to copy a file from one directory to another?

Should I create two CFile objects and copy one into the other character by character? Or is there something in the library that will do this for me?
I would just use the CopyFile Win32 API function, but the example code in the CFile::Open documentation shows how to copy files with CFile (using pretty much the method you suggest).
It depends on what you want to do. There are a number of ways to copy files:
CopyFile()
CopyFileEx()
SHFileOperation()
IFileOperation (replaces SHFileOperation() in Vista)
While I appreciate the previous answers, I have found that this FileOperations is a nice wrapper that mimics the way copy operations are performed in Windows Explorer, which also includes Copy, Move and Delete files and rename directories:
http://www.ucancode.net/Visual_C_Source_Code/Copy-Move-Delete-files-rename-directories-SHFileOperation-CFileFind-FindFirstFile-FindNextFile-mfc-example.htm
#include "stdafx.h"
#include "FileOperations.h"
//
// this code copy 'c:\source' directory and
// all it's subdirectories and files
// to the 'c:\dest' directory.
//
CFileOperation fo; // create object
fo.SetOverwriteMode(false); // reset OverwriteMode flag (optional)
if (!fo.Copy("c:\\source", "c:\\dest")) // do Copy
{
fo.ShowError(); // if copy fails show error message
}
//
// this code delete 'c:\source' directory and
// all it's subdirectories and files.
//
fo.Setucancode.netIfReadOnly(); // set ucancode.netIfReadonly flag (optional)
if (!fo.Delete("c:\\source")) // do Copy
{
fo.ShowError(); // if copy fails show error message
}
Here is the source code for completeness:
#include "resource.h"
#define PATH_ERROR -1
#define PATH_NOT_FOUND 0
#define PATH_IS_FILE 1
#define PATH_IS_FOLDER 2
class CFExeption
{
public:
CFExeption(DWORD dwErrCode);
CFExeption(CString sErrText);
CString GetErrorText() {return m_sError;}
DWORD GetErrorCode() {return m_dwError;}
private:
CString m_sError;
DWORD m_dwError;
};
//*****************************************************************************************************
class CFileOperation
{
public:
CFileOperation(); // constructor
bool Delete(CString sPathName); // delete file or folder
bool Copy(CString sSource, CString sDest); // copy file or folder
bool Replace(CString sSource, CString sDest); // move file or folder
bool Rename(CString sSource, CString sDest); // rename file or folder
CString GetErrorString() {return m_sError;} // return error description
DWORD GetErrorCode() {return m_dwError;} // return error code
void ShowError() // show error message
{MessageBox(NULL, m_sError, _T("Error"), MB_OK | MB_ICONERROR);}
void SetAskIfReadOnly(bool bAsk = true) // sets behavior with readonly files(folders)
{m_bAskIfReadOnly = bAsk;}
bool IsAskIfReadOnly() // return current behavior with readonly files(folders)
{return m_bAskIfReadOnly;}
bool CanDelete(CString sPathName); // check attributes
void SetOverwriteMode(bool bOverwrite = false) // sets overwrite mode on/off
{m_bOverwriteMode = bOverwrite;}
bool IsOverwriteMode() {return m_bOverwriteMode;} // return current overwrite mode
int CheckPath(CString sPath);
bool IsAborted() {return m_bAborted;}
protected:
void DoDelete(CString sPathName);
void DoCopy(CString sSource, CString sDest, bool bDelteAfterCopy = false);
void DoFileCopy(CString sSourceFile, CString sDestFile, bool bDelteAfterCopy = false);
void DoFolderCopy(CString sSourceFolder, CString sDestFolder, bool bDelteAfterCopy = false);
void DoRename(CString sSource, CString sDest);
bool IsFileExist(CString sPathName);
void PreparePath(CString &sPath);
void Initialize();
void CheckSelfRecursion(CString sSource, CString sDest);
bool CheckSelfCopy(CString sSource, CString sDest);
CString ChangeFileName(CString sFileName);
CString ParseFolderName(CString sPathName);
private:
CString m_sError;
DWORD m_dwError;
bool m_bAskIfReadOnly;
bool m_bOverwriteMode;
bool m_bAborted;
int m_iRecursionLimit;
};
//*****************************************************************************************************
C++ file:
#include "stdafx.h"
#include "resource.h"
#include "FileOperations.h"
//************************************************************************************************************
CFExeption::CFExeption(DWORD dwErrCode)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dwErrCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
m_sError = (LPTSTR)lpMsgBuf;
LocalFree(lpMsgBuf);
m_dwError = dwErrCode;
}
CFExeption::CFExeption(CString sErrText)
{
m_sError = sErrText;
m_dwError = 0;
}
//************************************************************************************************************
CFileOperation::CFileOperation()
{
Initialize();
}
void CFileOperation::Initialize()
{
m_sError = _T("No error");
m_dwError = 0;
m_bAskIfReadOnly = true;
m_bOverwriteMode = false;
m_bAborted = false;
m_iRecursionLimit = -1;
}
void CFileOperation::DoDelete(CString sPathName)
{
CFileFind ff;
CString sPath = sPathName;
if (CheckPath(sPath) == PATH_IS_FILE)
{
if (!CanDelete(sPath))
{
m_bAborted = true;
return;
}
if (!DeleteFile(sPath)) throw new CFExeption(GetLastError());
return;
}
PreparePath(sPath);
sPath += "*.*";
BOOL bRes = ff.FindFile(sPath);
while(bRes)
{
bRes = ff.FindNextFile();
if (ff.IsDots()) continue;
if (ff.IsDirectory())
{
sPath = ff.GetFilePath();
DoDelete(sPath);
}
else DoDelete(ff.GetFilePath());
}
ff.Close();
if (!RemoveDirectory(sPathName) && !m_bAborted) throw new CFExeption(GetLastError());
}
void CFileOperation::DoFolderCopy(CString sSourceFolder, CString sDestFolder, bool bDelteAfterCopy)
{
CFileFind ff;
CString sPathSource = sSourceFolder;
BOOL bRes = ff.FindFile(sPathSource);
while (bRes)
{
bRes = ff.FindNextFile();
if (ff.IsDots()) continue;
if (ff.IsDirectory()) // source is a folder
{
if (m_iRecursionLimit == 0) continue;
sPathSource = ff.GetFilePath() + CString("\\") + CString("*.*");
CString sPathDest = sDestFolder + ff.GetFileName() + CString("\\");
if (CheckPath(sPathDest) == PATH_NOT_FOUND)
{
if (!CreateDirectory(sPathDest, NULL))
{
ff.Close();
throw new CFExeption(GetLastError());
}
}
if (m_iRecursionLimit > 0) m_iRecursionLimit --;
DoFolderCopy(sPathSource, sPathDest, bDelteAfterCopy);
}
else // source is a file
{
CString sNewFileName = sDestFolder + ff.GetFileName();
DoFileCopy(ff.GetFilePath(), sNewFileName, bDelteAfterCopy);
}
}
ff.Close();
}
bool CFileOperation::Delete(CString sPathName)
{
try
{
DoDelete(sPathName);
}
catch(CFExeption* e)
{
m_sError = e->GetErrorText();
m_dwError = e->GetErrorCode();
delete e;
if (m_dwError == 0) return true;
return false;
}
return true;
}
bool CFileOperation::Rename(CString sSource, CString sDest)
{
try
{
DoRename(sSource, sDest);
}
catch(CFExeption* e)
{
m_sError = e->GetErrorText();
m_dwError = e->GetErrorCode();
delete e;
return false;
}
return true;
}
void CFileOperation::DoRename(CString sSource, CString sDest)
{
if (!MoveFile(sSource, sDest)) throw new CFExeption(GetLastError());
}
void CFileOperation::DoCopy(CString sSource, CString sDest, bool bDelteAfterCopy)
{
CheckSelfRecursion(sSource, sDest);
// source not found
if (CheckPath(sSource) == PATH_NOT_FOUND)
{
CString sError = sSource + CString(" not found");
throw new CFExeption(sError);
}
// dest not found
if (CheckPath(sDest) == PATH_NOT_FOUND)
{
CString sError = sDest + CString(" not found");
throw new CFExeption(sError);
}
// folder to file
if (CheckPath(sSource) == PATH_IS_FOLDER && CheckPath(sDest) == PATH_IS_FILE)
{
throw new CFExeption("Wrong operation");
}
// folder to folder
if (CheckPath(sSource) == PATH_IS_FOLDER && CheckPath(sDest) == PATH_IS_FOLDER)
{
CFileFind ff;
CString sError = sSource + CString(" not found");
PreparePath(sSource);
PreparePath(sDest);
sSource += "*.*";
if (!ff.FindFile(sSource))
{
ff.Close();
throw new CFExeption(sError);
}
if (!ff.FindNextFile())
{
ff.Close();
throw new CFExeption(sError);
}
CString sFolderName = ParseFolderName(sSource);
if (!sFolderName.IsEmpty()) // the source is not drive
{
sDest += sFolderName;
PreparePath(sDest);
if (!CreateDirectory(sDest, NULL))
{
DWORD dwErr = GetLastError();
if (dwErr != 183)
{
ff.Close();
throw new CFExeption(dwErr);
}
}
}
ff.Close();
DoFolderCopy(sSource, sDest, bDelteAfterCopy);
}
// file to file
if (CheckPath(sSource) == PATH_IS_FILE && CheckPath(sDest) == PATH_IS_FILE)
{
DoFileCopy(sSource, sDest);
}
// file to folder
if (CheckPath(sSource) == PATH_IS_FILE && CheckPath(sDest) == PATH_IS_FOLDER)
{
PreparePath(sDest);
char drive[MAX_PATH], dir[MAX_PATH], name[MAX_PATH], ext[MAX_PATH];
_splitpath(sSource, drive, dir, name, ext);
sDest = sDest + CString(name) + CString(ext);
DoFileCopy(sSource, sDest);
}
}
void CFileOperation::DoFileCopy(CString sSourceFile, CString sDestFile, bool bDelteAfterCopy)
{
BOOL bOvrwriteFails = FALSE;
if (!m_bOverwriteMode)
{
while (IsFileExist(sDestFile))
{
sDestFile = ChangeFileName(sDestFile);
}
bOvrwriteFails = TRUE;
}
if (!CopyFile(sSourceFile, sDestFile, bOvrwriteFails)) throw new CFExeption(GetLastError());
if (bDelteAfterCopy)
{
DoDelete(sSourceFile);
}
}
bool CFileOperation::Copy(CString sSource, CString sDest)
{
if (CheckSelfCopy(sSource, sDest)) return true;
bool bRes;
try
{
DoCopy(sSource, sDest);
bRes = true;
}
catch(CFExeption* e)
{
m_sError = e->GetErrorText();
m_dwError = e->GetErrorCode();
delete e;
if (m_dwError == 0) bRes = true;
bRes = false;
}
m_iRecursionLimit = -1;
return bRes;
}
bool CFileOperation::Replace(CString sSource, CString sDest)
{
if (CheckSelfCopy(sSource, sDest)) return true;
bool bRes;
try
{
bool b = m_bAskIfReadOnly;
m_bAskIfReadOnly = false;
DoCopy(sSource, sDest, true);
DoDelete(sSource);
m_bAskIfReadOnly = b;
bRes = true;
}
catch(CFExeption* e)
{
m_sError = e->GetErrorText();
m_dwError = e->GetErrorCode();
delete e;
if (m_dwError == 0) bRes = true;
bRes = false;
}
m_iRecursionLimit = -1;
return bRes;
}
CString CFileOperation::ChangeFileName(CString sFileName)
{
CString sName, sNewName, sResult;
char drive[MAX_PATH];
char dir [MAX_PATH];
char name [MAX_PATH];
char ext [MAX_PATH];
_splitpath((LPCTSTR)sFileName, drive, dir, name, ext);
sName = name;
int pos = sName.Find("Copy ");
if (pos == -1)
{
sNewName = CString("Copy of ") + sName + CString(ext);
}
else
{
int pos1 = sName.Find('(');
if (pos1 == -1)
{
sNewName = sName;
sNewName.Delete(0, 8);
sNewName = CString("Copy (1) of ") + sNewName + CString(ext);
}
else
{
CString sCount;
int pos2 = sName.Find(')');
if (pos2 == -1)
{
sNewName = CString("Copy of ") + sNewName + CString(ext);
}
else
{
sCount = sName.Mid(pos1 + 1, pos2 - pos1 - 1);
sName.Delete(0, pos2 + 5);
int iCount = atoi((LPCTSTR)sCount);
iCount ++;
sNewName.Format("%s%d%s%s%s", "Copy (", iCount, ") of ", (LPCTSTR)sName, ext);
}
}
}
sResult = CString(drive) + CString(dir) + sNewName;
return sResult;
}
bool CFileOperation::IsFileExist(CString sPathName)
{
HANDLE hFile;
hFile = CreateFile(sPathName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return false;
CloseHandle(hFile);
return true;
}
int CFileOperation::CheckPath(CString sPath)
{
DWORD dwAttr = GetFileAttributes(sPath);
if (dwAttr == 0xffffffff)
{
if (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_PATH_NOT_FOUND)
return PATH_NOT_FOUND;
return PATH_ERROR;
}
if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) return PATH_IS_FOLDER;
return PATH_IS_FILE;
}
void CFileOperation::PreparePath(CString &sPath)
{
if(sPath.Right(1) != "\\") sPath += "\\";
}
bool CFileOperation::CanDelete(CString sPathName)
{
DWORD dwAttr = GetFileAttributes(sPathName);
if (dwAttr == -1) return false;
if (dwAttr & FILE_ATTRIBUTE_READONLY)
{
if (m_bAskIfReadOnly)
{
CString sTmp = sPathName;
int pos = sTmp.ReverseFind('\\');
if (pos != -1) sTmp.Delete(0, pos + 1);
CString sText = sTmp + CString(" is read olny. Do you want delete it?");
int iRes = MessageBox(NULL, sText, _T("Warning"), MB_YESNOCANCEL | MB_ICONQUESTION);
switch (iRes)
{
case IDYES:
{
if (!SetFileAttributes(sPathName, FILE_ATTRIBUTE_NORMAL)) return false;
return true;
}
case IDNO:
{
return false;
}
case IDCANCEL:
{
m_bAborted = true;
throw new CFExeption(0);
return false;
}
}
}
else
{
if (!SetFileAttributes(sPathName, FILE_ATTRIBUTE_NORMAL)) return false;
return true;
}
}
return true;
}
CString CFileOperation::ParseFolderName(CString sPathName)
{
CString sFolderName = sPathName;
int pos = sFolderName.ReverseFind('\\');
if (pos != -1) sFolderName.Delete(pos, sFolderName.GetLength() - pos);
pos = sFolderName.ReverseFind('\\');
if (pos != -1) sFolderName = sFolderName.Right(sFolderName.GetLength() - pos - 1);
else sFolderName.Empty();
return sFolderName;
}
void CFileOperation::CheckSelfRecursion(CString sSource, CString sDest)
{
if (sDest.Find(sSource) != -1)
{
int i = 0, count1 = 0, count2 = 0;
for(i = 0; i < sSource.GetLength(); i ++) if (sSource[i] == '\\') count1 ++;
for(i = 0; i < sDest.GetLength(); i ++) if (sDest[i] == '\\') count2 ++;
if (count2 >= count1) m_iRecursionLimit = count2 - count1;
}
}
bool CFileOperation::CheckSelfCopy(CString sSource, CString sDest)
{
bool bRes = false;
if (CheckPath(sSource) == PATH_IS_FOLDER)
{
CString sTmp = sSource;
int pos = sTmp.ReverseFind('\\');
if (pos != -1)
{
sTmp.Delete(pos, sTmp.GetLength() - pos);
if (sTmp.CompareNoCase(sDest) == 0) bRes = true;
}
}
return bRes;
}
The Copy option in your code requires the dest file or folder to first exist otherwise this
if (CheckPath(sDest) == PATH_NOT_FOUND)
will always cause an error.