FindNextFile(...) dont "see" files WINAPI - c++

My question is: why my output is given me the "recycle.bin" file, and that's all nothing else, like it wouldn't be any files in there ("C:\*" / "D:\*")
after i call FindNextFile() i get error 18 (no more files in directory), the problem is, that it's wrong
bool data_confersion(PWIN32_FIND_DATAW pFileData, P_SINGLE_FILE pFile){
//file sieze determining
pFile->filesize = pFileData->nFileSizeLow;
((int*)&pFile->filesize)[1] = pFileData->nFileSizeHigh;
pFile->attributes = pFileData->dwFileAttributes;
pFile->name = new WCHAR[MAX_PATH];
for(int i=0; i<MAX_PATH; i++){
pFile->name[i] = pFileData->cFileName[i];
}
if(FileTimeToSystemTime(&pFileData->ftCreationTime, &pFile->CreationTime) ||
FileTimeToSystemTime(&pFileData->ftLastAccessTime, &pFile->LastAccessTime) ||
FileTimeToSystemTime(&pFileData->ftLastWriteTime, &pFile->LastWriteTime))
return false;
return true;
}
bool FILESYSTEM::updateFolderContent(P_DRIVE _d){
LPTSTR t = new wchar_t[128];
int i=0;
P_SINGLE_FILE p_t_file;
bool b_found = false;
int i_filesCount = 0;
for(; _d->logicalDrives[i]!=L'\0'; i++)
t[i]=_d->logicalDrives[i];
t[i]=L'*';
t[i+1]=0;
LPVOID v;
WIN32_FIND_DATAW p;
Wow64DisableWow64FsRedirection(&v);
HANDLE hFind = FindFirstFile(t, &p);
//SCANING FOR NEXT FILES
do{
//LOOP CHECKING IF FILE IS SAVED IN DATA BASE
i_filesCount++;
for(int i=0; i<_d->content.size; i++){
p_t_file = _d->content[i];
for(int j=0; p_t_file->name[i]!=0; i++){
if(p_t_file->name[i]!=p.cFileName[i])
b_found = true;
}
}
if(!b_found){
p_t_file = new SINGLE_FILE;
_d->content.push(p_t_file);
data_confersion(&p , p_t_file);
}
b_found = false;
}while(FindNextFile(hFind, &p));
int err = GetLastError();
if(!FindClose(hFind)){
err = GetLastError();
}
if(i_filesCount < _d->content.size){
for(int i=0; i<_d->content.size; i++){
p_t_file = _d->content[i];
if(INVALID_FILE_ATTRIBUTES == GetFileAttributes(p_t_file->name)){
int err = GetLastError();
_d->content.pop(i);
i--;
}
}
}
Wow64RevertWow64FsRedirection(v);
return true;
}

Your t string is most likely wrong. It's basically logicalDrives (plural) with a single * appended. That's rather unlikely to be correct.

Related

C++ GetModuleFileName does not return correct strings

Sometimes GetModuleFileName returns the correct string, however 99% of the time currently with current code I am using the string returns as ÀÙáøÛáws\system32\HID.DLL instead of E:\Windows\system32\HID.DLL that should be the correct value. With this in mind I can't compare the string with an list of all modules that should be loaded to see if that string is in the list, if not someone injected that DLL.
This code below might not be the best, however it is the code I attempted to use for this. I did try all sorts of code changes to try to figure it out like not using TCHAR and investigating the returns from EnumProcessModules.
void _scan_dll_data(VBTrpSetup_t &setup, VBTrp_DetectData_t &_ret, VBTrp_InjectData_t &_dlllists) {
bool _detected_injected_dll = false;
std::vector<std::string> _ModuleContainer;
std::string _ModuleName;
HMODULE hMods[1024]; /* Hopefully enough for this. */
DWORD cbNeeded;
if (EnumProcessModules(setup.GameProcHandle, hMods, sizeof(hMods), &cbNeeded)) {
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ ) {
char szModName[MAX_PATH];
if (GetModuleFileName(hMods[i], szModName, sizeof(szModName) / sizeof(char))) {
_ModuleName = szModName;
for (unsigned int i = 0; i < _dlllists.ModuleExcludeList.size(); i++) {
// item must not be in the ModuleExcludeList!!!
if (!_dlllists.ModuleExcludeList[i].compare(_ModuleName)) {
_ModuleContainer.push_back(_ModuleName);
}
}
}
}
}
if (_dlllists.ModuleList != _ModuleContainer) {
_detected_injected_dll = true;
_ret.DLLName = reinterpret_cast<LPCSTR>(_ModuleName.c_str());
}
if (_detected_injected_dll) {
_ret.value = TRUE;
}
else {
_ret.value = FALSE;
}
if (_ret.value == TRUE) {
_ret.int_value = -1;
} else {
_ret.int_value = NULL;
}
}
Hopefully the answer is something simple that I must have missed. I did do some parts of this according to MSDN examples. Maybe those examples was wrong. I am not so sure.
Does anyone know how to fix this string issue it returns?
The fix was to definately use the Unicode versions and to make the whole function use wide unicode strings. And the reason for this is because of a struct (related to PEB) that is internal and undocumented to ntdll.dll.
So, basically changing everything to the GetModuleBaseNameW function because of the fact I was going to basename them anyway later, the wstring, noticing a second loop using i causing an overwrite of the i on the outer for loop and removing it, and adding checks on GetLastError for when the Handle is invalidated and toreturn the error code to the end user to handle cleanup.
The result is then this code:
void _scan_dll_data(VBTrpSetup_t &setup, VBTrp_DetectData_t &_ret, VBTrp_InjectData_t &_dlllists) {
BOOL _detected_injected_dll = FALSE;
std::vector<std::wstring> _ModuleContainer;
HANDLE hProcess;
std::vector<HMODULE> hMods;
DWORD cbNeeded;
hProcess = GetCurrentProcess();
_ret.int_value = 0;
if (EnumProcessModulesEx(hProcess, hMods.data(), setup.NumOfModules, &cbNeeded, LIST_MODULES_ALL)) {
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
wchar_t *szModName = L'\x0';
std::wstring _ModuleName;
if (GetModuleBaseNameW(hProcess, hMods[i], reinterpret_cast<LPWSTR>(szModName), MAX_PATH)) {
_ModuleName = szModName;
// item must not be in the ModuleExcludeList!!!
if (!_dlllists.ModuleExcludeList[i].compare(_ModuleName)) {
_ModuleContainer.push_back(_ModuleName);
}
} else {
_ret.error_code = GetLastError();
}
}
} else {
_ret.error_code = GetLastError();
}
if (_ret.error_code != ERROR_INVALID_HANDLE) {
for (unsigned int j = 0; j < _dlllists.ModuleList.size(); j++) {
if (_dlllists.ModuleList[j] != _ModuleContainer[j]) {
_detected_injected_dll = TRUE;
_ret.int_value = -1;
_ret.DLLName = (LPWSTR)_ModuleContainer[j].c_str();
// to avoid overwriting the first one.
break;
}
}
_ret.value = _detected_injected_dll;
}
}

Sometimes getting null value for windows version and processor type

For the most part, the function below works but in rare cases returns a null value:
DWORD WinVerMinor() {
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
return osvi.dwMinorVersion;
}
Also cpustr below sometimes ends up being null. For example, from an executable app cpustr stores the correct string while the very same code produces a null result in a dll (sometimes).
char cpustr[255]
void proctype()
{
int nBuff[4];
char szMan[13];
char szFeatures[256];
unsigned nProcessorType;
// Get CPU manufacturer and highest CPUID
__cpuid(nBuff, 0);
nHighestFeature = (unsigned)nBuff[0];
*(int*)&szMan[0] = nBuff[1];
*(int*)&szMan[4] = nBuff[3];
*(int*)&szMan[8] = nBuff[2];
szMan[12] = 0;
if(strcmp(szMan, "AuthenticAMD") == 0)
nProcessorType = 0;
else if(strcmp(szMan, "GenuineIntel") == 0)
nProcessorType = 1;
else
nProcessorType = 2;
__cpuid(nBuff, 0x80000000);
nHighestFeatureEx = (unsigned)nBuff[0];
if(nHighestFeatureEx >= 0x80000004)
{
char szCPUName[49];
szCPUName[0] = 0;
__cpuid((int*)&szCPUName[0], 0x80000002);
__cpuid((int*)&szCPUName[16], 0x80000003);
__cpuid((int*)&szCPUName[32], 0x80000004);
szCPUName[48] = 0;
for(int i=(int)strlen(szCPUName)-1; i>=0; --i)
{
if(szCPUName[i] == ' ')
szCPUName[i] = '\0';
else
break;
}
for (int z=0; z < strlen(szCPUName); z++) {
cpustr[z] = szCPUName[z]; }
}
return 0;
}
What is the reason for the (sometimes) null values?

GetLogicalDriveStrings() and char - Where am I doing wrongly

I want to search a file which may be present in any drives such as C:\, D:\ etc. Using GetLogicalDriveStrings I can able to get the list of drives but when I add anything extra for the output, I am getting a null in the output prompt. Here is my code:
#include "StdAfx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
// Buffer length
DWORD mydrives = 100;
// Buffer for drive string storage
char lpBuffer[100];
const char *extFile = "text.ext";
// You may want to try the wmain() version
int main(void)
{
DWORD test;
int i;
test = GetLogicalDriveStrings(mydrives, (LPWSTR)lpBuffer);
if(test != 0)
{
printf("GetLogicalDriveStrings() return value: %d, Error (if any): %d \n", test, GetLastError());
printf("The logical drives of this machine are:\n");
// Check up to 100 drives...
for(i = 0; i<100; i++)
printf("%c%s", lpBuffer[i],extFile);
printf("\n");
}
else
printf("GetLogicalDriveStrings() is failed lor!!! Error code: %d\n", GetLastError());
_getch();
return 0;
}
I want above output as C:\text.ext D:\text.ext ... rather I am getting text.ext only. I am using Microsoft Visual C++ 2010 Express
GetLogicalDriveStrings() returns a double-null terminated list of null-terminated strings. E.g., say you had drives A, B and C in your machine. The returned string would look like this:
A:\<nul>B:\<nul>C:\<nul><nul>
You can use the following code to iterate through the strings in the returned buffer and print each one in turn:
DWORD dwSize = MAX_PATH;
char szLogicalDrives[MAX_PATH] = {0};
DWORD dwResult = GetLogicalDriveStrings(dwSize,szLogicalDrives);
if (dwResult > 0 && dwResult <= MAX_PATH)
{
char* szSingleDrive = szLogicalDrives;
while(*szSingleDrive)
{
printf("Drive: %s\n", szSingleDrive);
// get the next drive
szSingleDrive += strlen(szSingleDrive) + 1;
}
}
Note that the details of how the function works, including the example code that I shamelessly copied and pasted, can be found by reading the docs.
Did you mean to put the printf in the loop?
Currently, you set extFile 100 times (just to be sure?!)
for(i = 0; i<100; i++)
extFile = "text.ext";
You meant to show all the drive letters in a loop:
for(i = 0; i<100; i++)
{
extFile = "text.ext";
printf("%c%s", lpBuffer[i], extFile); //I guess you mean extFile here?
}
DWORD dwSize = MAX_PATH;
WCHAR szLogicalDrives[MAX_PATH] = { 0 };
DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives);
CStringArray m_Drives;
m_Drives.RemoveAll();
if (dwResult > 0 && dwResult <= MAX_PATH)
{
WCHAR* szSingleDrive = szLogicalDrives;
while (*szSingleDrive)
{
UINT nDriveType = GetDriveType(szSingleDrive);
m_Drives.Add(CString(szSingleDrive, 2));
// get the next drive
szSingleDrive += wcslen(szSingleDrive) + 1;
}
}
return m_Drives;
class DriveList {
protected:
LPTSTR m_driveList;
DWORD m_driveCount;
DWORD m_bufSize = 32 * sizeof(TCHAR);
public:
virtual ~DriveList() {
free(m_driveList);
}
DriveList() {
m_driveList = (LPTSTR)malloc(m_bufSize);
}
int getDriveCount() const {
return m_driveCount;
}
TCHAR operator[] (const int index) const {
return m_driveList[index];
}
void loadDriveList() {
DWORD mask;
if((mask = GetLogicalDrives()) == 0) {
throw;
}
m_driveCount = 0;
for(int x = 0; x <= 25; x++ ) {
if(mask & 1) {
m_driveList[m_driveCount] = TCHAR(65 + x);
m_driveCount += 1;
}
mask >>= 1;
}
}
};

FMOD playSound throws an error about invalid parameter

I've tried building some sort of audio manager after openAL failed to deliver on certain machines so I found out about fmod. However after few hours of changes in code nothing really works. My playSound call seems to be bugging.
An invalid parameter was passed to this function.
This is exactly what an errorcheck output gives me.
Code...let's get from start:
typedef std::map<std::string, FMOD::Sound*> SoundPool;
SoundPool m_sounds;
FMOD::Channel* m_soundChannels[MAX_SOUNDS];
FMOD::System* m_soundSystem;
and then:
FMOD::System_Create(&m_soundSystem);
m_soundSystem->init(32, FMOD_INIT_NORMAL, NULL);
for(int i = 0; i < MAX_SOUNDS; i++)
m_soundChannels[i] = 0;
and later:
void CResourceManager::PlaySound(std::string filename, float volume)
{
for(int i = 0; i < MAX_SOUNDS; i++)
{
if(m_soundChannels[i] == 0)
{
if(volume > 1.0f) volume = 1.0f;
FMOD_RESULT result = m_soundSystem->playSound(FMOD_CHANNEL_FREE,
m_sounds[filename], false, &m_soundChannels[i]);
if(result != FMOD_OK)
{
std::cout << FMOD_ErrorString(result); //// here's the error
}
m_soundChannels[i]->setVolume(volume);
break;
}
}
}
void CResourceManager::Update()
{
m_soundSystem->update();
for(int i = 0; i < MAX_SOUNDS; i++)
{
if(m_soundChannels[i] != 0)
{
bool playing;
m_soundChannels[i]->isPlaying(&playing);
if(!playing)
m_soundChannels[i] = 0;
}
}
}
bool CResourceManager::AddSound( std::string filename )
{
FMOD_RESULT result = m_soundSystem->createSound(filename.c_str(),
FMOD_LOOP_NORMAL, NULL, &m_sounds[filename]);
if(result == FMOD_OK)
return true;
return false;
}

Send mail with Mapi with reply-to multiple emails

I'm working with MAPI library in C++ to send emails. Now I need that the emails I send have a reply-to set to more than one email and I just can do it to one email.
I have been reading that to be able to do this I need to work with the objects FLATENTRYLIST (link) and FLATENTRY (link).
My doubt is how can I store more than one FLATENTRY object in the FLATENTRYLIST. My experience in C++ is not very high so if anyone can help me I will apreciate.
Thanks in advance
Paulo
The FLATENTRYLIST has cEntries member that determines the number of the entries in the list.
You just need to store the entries in abEntries array.
Here is the solution I developed - http://www.codeproject.com/KB/IP/CMapiEx.aspx?msg=3959770#xx3959770xx
Thanks Dmitry for your help.
When I was copying the EntryID to the FlatEntry I as copying the wrong bytes number. Here is the final code that works like a charm.
BOOL CMAPIMessage::SetReplyTo(LPADRLIST lpAddrList)
{
HRESULT hRes = S_OK;
SPropValue pspvReply[1];
LPFLATENTRYLIST lpEntryList = NULL;
BOOL bResult = false;
CString m_strReplyToNames;
int cb = 0;
int displayNameTagID = -1;
int emailTagID = -1;
int entryIDTagID = -1;
int cbAllBytes = 0;
//Get all the EntryID's bytes to initalize the FLATENTRYLIST
for(unsigned j=0; j<lpAddrList->cEntries; j++)
{
for (unsigned i = 0; i < lpAddrList->aEntries[j].cValues; i++)
{
if (lpAddrList->aEntries[j].rgPropVals[i].ulPropTag == PR_ENTRYID)
{
entryIDTagID = i;
}
}
if (entryIDTagID >= 0)
{
int feBytes = CbNewFLATENTRY(lpAddrList->aEntries[j].rgPropVals[entryIDTagID].Value.bin.cb);
cbAllBytes += feBytes;
cbAllBytes += ((feBytes + 4 & ~3) - feBytes);
}
}
//Allocate a new FLATENTRYLIST with all flatentries bytes
cb = CbNewFLATENTRYLIST(cbAllBytes);
hRes = MAPIAllocateBuffer(cb, (LPVOID *)&lpEntryList);
if (FAILED(hRes))
{
bResult = false;
goto Cleanup;
}
ZeroMemory((VOID *)lpEntryList, cb);
// Copy the bits of the FLATENTRY into the FLATENTRYLIST.
lpEntryList->cEntries = lpAddrList->cEntries;
int countBytesAdded = 0;
for(unsigned j=0; j<lpAddrList->cEntries; j++)
{
for (unsigned i = 0; i < lpAddrList->aEntries[j].cValues; i++)
{
if (lpAddrList->aEntries[j].rgPropVals[i].ulPropTag == PR_TRANSMITABLE_DISPLAY_NAME)
{
displayNameTagID = i;
}
else if (lpAddrList->aEntries[j].rgPropVals[i].ulPropTag == PR_EMAIL_ADDRESS)
{
emailTagID = i;
}
else if (lpAddrList->aEntries[j].rgPropVals[i].ulPropTag == PR_ENTRYID)
{
entryIDTagID = i;
}
}
if ((emailTagID>=0) && (entryIDTagID>=0))
{
CString m_strReplyToName;
CString m_strReplyToEmail;
m_strReplyToEmail=lpAddrList->aEntries[j].rgPropVals[emailTagID].Value.lpszA;
if(displayNameTagID>=0)
m_strReplyToName=lpAddrList->aEntries[j].rgPropVals[displayNameTagID].Value.lpszA;
else
m_strReplyToName = m_strReplyToEmail;
m_strReplyToNames += (CString)m_strReplyToName + ";";
// Allocate a new FLATENTRY structure for the PR_REPLY_RECIPIENT_ENTRIES property
LPFLATENTRY lpReplyEntry = NULL;
cb = CbNewFLATENTRY(lpAddrList->aEntries[j].rgPropVals[entryIDTagID].Value.bin.cb);
hRes = MAPIAllocateBuffer(cb, (LPVOID *)&lpReplyEntry);
if (FAILED(hRes))
{
bResult = false;
goto Cleanup;
}
ZeroMemory((VOID *)lpReplyEntry, cb);
// Copy the bits of the entry id into the FLATENTRY structure
CopyMemory(lpReplyEntry->abEntry,
lpAddrList->aEntries[j].rgPropVals[entryIDTagID].Value.bin.lpb,
lpAddrList->aEntries[j].rgPropVals[entryIDTagID].Value.bin.cb);
lpReplyEntry->cb = lpAddrList->aEntries[j].rgPropVals[entryIDTagID].Value.bin.cb;
int missingBytes = 0;
int feBytes = CbFLATENTRY(lpReplyEntry);
missingBytes = ((feBytes + 4 & ~3) - feBytes);
//Copy each FLATENTRY to the abEntries, next to the previous added bytes
CopyMemory(lpEntryList->abEntries + countBytesAdded, lpReplyEntry, feBytes);
countBytesAdded += feBytes + missingBytes;
//Clean Memory
if (lpReplyEntry) MAPIFreeBuffer(lpReplyEntry);
}
displayNameTagID = -1;
emailTagID = -1;
entryIDTagID = -1;
}
lpEntryList->cbEntries = countBytesAdded;
pspvReply[0].ulPropTag = PR_REPLY_RECIPIENT_ENTRIES;
// Allocate memory in the lpb to hold the FLATENTRYLIST
hRes = MAPIAllocateBuffer(CbFLATENTRYLIST(lpEntryList), (LPVOID *)&pspvReply[0].Value.bin.lpb);
if (FAILED(hRes))
{
bResult = false;
goto Cleanup;
}
// Copy the memory into the SPropValue
CopyMemory(pspvReply[0].Value.bin.lpb,lpEntryList,CbFLATENTRYLIST(lpEntryList));
pspvReply[0].Value.bin.cb = CbFLATENTRYLIST(lpEntryList);
//Set the PR_REPLY_RECIPIENT_NAMES property with all names
SetPropertyString(PR_REPLY_RECIPIENT_NAMES, m_strReplyToNames);
// Set the property that contains the FLATENTRYLIST with the reply-to adresses to the message properties
hRes = Message()->SetProps(1,pspvReply,NULL);
if (FAILED(hRes))
{
bResult = false;
goto Cleanup;
}
bResult = true;
Cleanup:
if (lpEntryList) MAPIFreeBuffer(lpEntryList);
return bResult;
}