Adding To A Map - windows

I'm trying to add the file size to this map. It looks like I'm making a mess of things. Any help is appreciated. Thank you.
int GetFileList(const wchar_t *searchkey, std::map<std::wstring, std::wstring> &map)
{
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(searchkey,&fd);
if(h == INVALID_HANDLE_VALUE)
{
return 0; // no files found
}
while(1)
{
wchar_t buf[128];
FILETIME ft = fd.ftLastWriteTime;
SYSTEMTIME sysTime;
FileTimeToSystemTime(&ft, &sysTime);
wsprintf(buf, L"%d-%02d-%02d",sysTime.wYear, sysTime.wMonth, sysTime.wDay);
map[fd.cFileName] = buf;
map[fd.nFileSizeHigh] = buf;
map[fd.nFileSizeLow] = buf;
if(FindNextFile(h, &fd) == FALSE)
break;
}
return map.size();
}
void main()
{
std::map<std::wstring, std::wstring> map;
int count = GetFileList(L"C:\\Users\\DS\\Downloads\\*.zip", map)
&& GetFileList(L"C:\\Users\\DS\\Downloads\\*.txt", map);
for(std::map<std::wstring, std::wstring>::const_iterator it = map.begin();
it != map.end(); ++it)
{
//MessageBoxW(NULL,it->first.c_str(),L"File Name",MB_OK);
//MessageBoxW(NULL,it->second.c_str(),L"File Date",MB_OK);
}
}

Well, you need to decide what you're mapping from, and what you're mapping to.
Probably you want to map from file-name to struct {file-size, file-time}.
Keeping it similar to your code:
struct file_data
{
wstring sLastAccessTime;
__int64 nFileSize ;
};
int GetFileList(const wchar_t *searchkey, std::map<std::wstring, file_data> &map)
{
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(searchkey,&fd);
if(h == INVALID_HANDLE_VALUE)
{
return 0; // no files found
}
while(1)
{
wchar_t buf[128];
FILETIME ft = fd.ftLastWriteTime;
SYSTEMTIME sysTime;
FileTimeToSystemTime(&ft, &sysTime);
wsprintf(buf, L"%d-%02d-%02d",sysTime.wYear, sysTime.wMonth, sysTime.wDay);
file_data filedata;
filedata.sLastAccessTime= buf;
filedata.nFileSize = (((__int64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow;
map[fd.cFileName]= filedata;
if (FindNextFile(h, &fd) == FALSE)
break;
}
return map.size();
}
int main()
{
std::map<std::wstring, file_data> map;
GetFileList(L"C:\\Users\\DS\\Downloads\\*.zip", map);
GetFileList(L"C:\\Users\\DS\\Downloads\\*.txt", map);
for(std::map<std::wstring, file_data>::const_iterator it = map.begin();
it != map.end(); ++it)
{
MessageBoxW(NULL,it->first.c_str(),L"File Name",MB_OK);
MessageBoxW(NULL,it->second.sLastAccessTime.c_str(),L"File Date",MB_OK);
}
return 0;
}

Related

Mac C++ Broadcast -> more then one network-interface

I have a broadcast program on my mac, everything is working fine, but if i have more then one network interface, he didn't recieve anything.
So what i now want to do is:
Check which network interfaces are activ on the mac
send to every activ interface a broadcast ( so i have to select which interface i want to use)
recieve the answer (if there is one :) )
Interesting:
the broadcast client is on my WLAN (with a router beetween the devices) and a normal internet connection is on my LAN. If i deactivate the LAN in the system configs, he also didn't find my other device, but if i pull the cable he found the other device... So maybe i didn't have to look which interface is activ and have a look to which interface is connected.
Do u have some tipps or good google keywords for me to do that?
Long time ago, but if someone find my post, here is my solution:
#include <stdint.h>
static uint32 Inet_AtoN(const char * buf)
{
// net_server inexplicably doesn't have this function; so I'll just fake it
uint32 ret = 0;
int shift = 24; // fill out the MSB first
bool startQuad = true;
while ((shift >= 0) && (*buf))
{
if (startQuad)
{
unsigned char quad = (unsigned char)atoi(buf);
ret |= (((uint32)quad) << shift);
shift -= 8;
}
startQuad = (*buf == '.');
buf++;
}
return ret;
}
int Broadcast::BroadcastToAllInterfaces()
{
DEBUG_LOG(1,"Start Broadcast To All Interfaces", "DEv1");
globalDatabase->SetInBroadcast();
moreThenOne = 0;
#if defined(USE_GETIFADDRS)
struct ifaddrs * ifap;
if (getifaddrs(&ifap) == 0)
{
struct ifaddrs * p = ifap;
while (p)
{
uint32 ifaAddr = SockAddrToUint32(p->ifa_addr);
uint32 maskAddr = SockAddrToUint32(p->ifa_netmask);
uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr);
if (ifaAddr > 0)
{
char ifaAddrStr[32]; Inet_NtoA(ifaAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(maskAddr, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(dstAddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
addr << dstAddrStr;
descss << p->ifa_name;
descss >> descs;
addr >> addrs;
DoABroadcast(dstAddr);
}
p = p->ifa_next;
}
freeifaddrs(ifap);
}
#elif defined(WIN32)
// Windows XP style implementation
// Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx
// Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable()
// multiple times in order to deal with potential race conditions properly.
MIB_IPADDRTABLE * ipTable = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false);
if (ipRet == ERROR_INSUFFICIENT_BUFFER)
{
free(ipTable); // in case we had previously allocated it STILL_RUN
ipTable = (MIB_IPADDRTABLE *)malloc(bufLen);
}
else if (ipRet == NO_ERROR) break;
else
{
free(ipTable);
ipTable = NULL;
break;
}
}
}
if (ipTable)
{
IP_ADAPTER_INFO * pAdapterInfo = NULL;
{
ULONG bufLen = 0;
for (int i = 0; i<5; i++)
{
DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen);
if (apRet == ERROR_BUFFER_OVERFLOW)
{
free(pAdapterInfo); // in case we had previously allocated it
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(bufLen);
}
else if (apRet == ERROR_SUCCESS) break;
else
{
free(pAdapterInfo);
pAdapterInfo = NULL;
break;
}
}
}
for (DWORD i = 0; i<ipTable->dwNumEntries; i++)
{
const MIB_IPADDRROW & row = ipTable->table[i];
// Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it
const char * name = NULL;
const char * desc = NULL;
if (pAdapterInfo)
{
IP_ADAPTER_INFO * next = pAdapterInfo;
while ((next) && (name == NULL))
{
IP_ADDR_STRING * ipAddr = &next->IpAddressList;
while (ipAddr)
{
if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr))
{
name = next->AdapterName;
desc = next->Description;
break;
}
ipAddr = ipAddr->Next;
}
next = next->Next;
}
}
char buf[128];
int setUnnamed = 0;
if (name == NULL)
{
sprintf(buf, "unnamed");
name = buf;
setUnnamed = 1;
}
uint32 ipAddr = ntohl(row.dwAddr);
uint32 netmask = ntohl(row.dwMask);
uint32 baddr = ipAddr & netmask;
if (row.dwBCastAddr) baddr |= ~netmask;
char ifaAddrStr[32]; Inet_NtoA(ipAddr, ifaAddrStr);
char maskAddrStr[32]; Inet_NtoA(netmask, maskAddrStr);
char dstAddrStr[32]; Inet_NtoA(baddr, dstAddrStr);
std::stringstream addr, descss;
std::string addrs, descs;
if (setUnnamed == 0)
{
addr << dstAddrStr;
descss << desc;
descss >> descs;
addr >> addrs;
DoABroadcast(baddr);
}
}
free(pAdapterInfo);
free(ipTable);
}
#else
// Dunno what we're running on here!
# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!"
#endif
globalDatabase->SetLeaveBroadcast();
return 1;
}
int Broadcast::DoABroadcast(uint32 broadAddr)
{
int askSinlen = sizeof(struct sockaddr_in);
int askBuflen = MAXBUF;
int message;
char buf[512];
int status;
char askBuffer[MAXBUF];
struct sockaddr_in sock_in, client_adress, client_adress2;
#ifdef __APPLE__
socklen_t clientLength;
int askYes = 1;
#else
char askYes = 1;
int clientLength;
WSADATA w;
int result = WSAStartup(MAKEWORD(2, 2), &w);
#endif
int recSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (recSocket <0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
sock_in.sin_addr.s_addr = htonl(INADDR_ANY);
sock_in.sin_port = htons(4028);
sock_in.sin_family = PF_INET;
client_adress.sin_family = PF_INET;
client_adress.sin_port = htons(4029);
client_adress.sin_addr.s_addr = htonl(broadAddr);
askSinlen = sizeof(sock_in);
client_adress2.sin_family = AF_INET;
client_adress2.sin_port = htons(4028);
client_adress2.sin_addr.s_addr = htonl(0xc0a8b2ff);
status = setsockopt(recSocket, SOL_SOCKET, SO_BROADCAST, &askYes, sizeof(askYes));
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
status = bind(recSocket, (struct sockaddr *)&sock_in, askSinlen);
if (status < 0)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 10;
}
askBuflen = sprintf(askBuffer, "Ciao Mac ist hier");
status = sendto(recSocket, askBuffer, askBuflen, 0, (struct sockaddr *)&client_adress, sizeof(client_adress));
fd_set fds;
struct timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(recSocket, &fds);
int ret;
if ((ret = select(recSocket +1, &fds, NULL, NULL, &tv)) > 0)
{
int e = 0;
while ((ret = select(recSocket + 1, &fds, NULL, NULL, &tv)) > 0)
{
clientLength = sizeof(client_adress2);
message = recvfrom(recSocket, buf, sizeof(buf), 0, (struct sockaddr*) &client_adress2, &clientLength);
if (message == -1)
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -5;
}
else
{
std::string hereisyourbroadcast(buf);
}
}
}
else
{
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return -6;
}
#ifdef __APPLE__
close(recSocket);
#else
closesocket(recSocket);
#endif
inBroadcast = false;
return 1;
}

Can I Write Version Information API For Both CHAR And WCHAR?

I'm a little bit short of reaching my goal.
GetFileVersionInfoSize() is working fine along with other two functions GetFileVersionInfo() and VerQueryValue(). I would like to just add more features to it to make it complete.
I've coded it to run on WCHAR and would like to know making it run for CHAR would make sense?
Is there a way around it so that I code it once and it would work for both?
Also, is there a way I could enumerate the contents of \\StringFileInfo\\lang-codepage\\* ?
DWORD GetFileVersionInfo3(const TCHAR *pszFilePath, std::vector<std::pair<std::wstring, std::wstring>> *lplist)
{
DWORD dwSize = 0;
BYTE *pbVersionInfo = NULL;
VS_FIXEDFILEINFO *pFileInfo = NULL;
UINT puLenFileInfo = 0;
dwSize = GetFileVersionInfoSize(pszFilePath, NULL);
if (dwSize == 0)
{
printf("\nError in GetFileVersionInfoSize: %d\n", GetLastError());
return 1;
}
pbVersionInfo = new BYTE[dwSize];
memset(pbVersionInfo, '\0', dwSize);
if (!GetFileVersionInfo(pszFilePath, 0, dwSize, pbVersionInfo))
{
printf("\nError in GetFileVersionInfo: %d\n", GetLastError());
delete[] pbVersionInfo;
return 1;
}
if (!VerQueryValue(pbVersionInfo, TEXT("\\"), (LPVOID*)&pFileInfo, &puLenFileInfo))
{
printf("\nError in VerQueryValue: %d\n", GetLastError());
delete[] pbVersionInfo;
return 1;
}
if (!VerQueryValue(pbVersionInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &puLenFileInfo))
{
printf("\nError in VerQueryValue: %d\n", GetLastError());
return 1;
}
std::vector<std::wstring>::iterator itr;
std::vector<std::wstring> wlist;
wlist.clear();
wlist.push_back(L"FileDescription");
wlist.push_back(L"InternalName");
wlist.push_back(L"OriginalFilename");
wlist.push_back(L"CompanyName");
wlist.push_back(L"FileVersion");
wlist.push_back(L"ProductName");
wlist.push_back(L"ProductVersion");
wlist.push_back(L"LegalCopyright");
char fileEntry[1024];
for (int i = 0; i < (puLenFileInfo / sizeof(struct LANGANDCODEPAGE)); i++)
{
sprintf_s(fileEntry, 1024, "\\StringFileInfo\\%04x%04x\\",
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
lplist->push_back(std::pair<std::wstring, std::wstring>(L"File: ", pszFilePath));
std::string s1(fileEntry);
for (itr = wlist.begin(); itr != wlist.end(); itr++)
{
std::wstring item = *itr;
std::wstring wstr;
wstr.append(s1.begin(), s1.end());
wstr.append(item);
LPVOID lpBuffer = NULL;
UINT dwBytes = 0;
bool bRes = VerQueryValue(pbVersionInfo, wstr.c_str(), (LPVOID*)&lpBuffer, &dwBytes);
if (!bRes)
{
continue;
}
LPTSTR wsResult;
wsResult = (LPTSTR)lpBuffer;
lplist->push_back(std::pair<std::wstring, std::wstring>(item, wsResult));
}
}
return 0;
}
Since you are using TCHAR, use std:::basic_string<TCHAR> instead of std::wstring to match. Otherwise, drop TCHAR and use WCHAR for everything.

Developing with Firefox SDK with IDE (Visual Studio 2013 maybe)

I started developing a Firefox add-on, however I could not find any IDE specifically for Firefox. For most part it doesn't really matter because I can just open Javascript files and edit them (I use VS2013 and Web Essentials (I think)).
Up to this point everything is acceptable, but when I have to use cmd every time to run this plugin and then read console logs from cmd, it becomes a nightmare.
So my is - is there some way to launch, develop and log Firefox plugin just like any code in Visual Studio 2013? Other IDEs are welcome too.
Well I think it would be possible to create Visual Studio add-on, but it just too much work. However, I managed to partly integrate Firefox add-on creation into VS2013 with c++ code. It redirects cmd window so that means, that you'll output from cmd in "Output" window while debugging.
I'm leaving complete code with steps in case someone else needs this (C++11 is required):
Create Win32 C++ project (not cmd one).
Paste code (below) into cpp file.
Change YOUR_EXTENSION_NAME to your add-on name.
Run code once, it should throw message box with info where to put Add-on SDK.
Copy SDK files to that folder.
Run code again and exit (you may exit however you want, it should terminate remaining windows).
Now there are 3 options for file (.js, .css, etc.) linking:
Create files manually in SDK folder and add them manually to project.
Create files via VS2013 menu and then uncomment and modify, add, delete lines in do while loop.
Create files via VS2013 menu, but choose SDK folders.
Code:
#include <windows.h>
#include <tchar.h>
#include <thread>
#include <chrono>
#include <typeinfo>
#include <Shlwapi.h>
#pragma comment(lib,"Shlwapi.lib")
// Timer code start
/*
//
//Credit goes to James Daughtry for this piece of code
//
*/
class Timer {
typedef std::chrono::high_resolution_clock high_resolution_clock;
typedef std::chrono::milliseconds milliseconds;
public:
Timer(bool run = false)
{
if (run) Reset();
}
void Reset()
{
_start = high_resolution_clock::now();
}
milliseconds Elapsed() const
{
return std::chrono::duration_cast<milliseconds>(high_resolution_clock::now() - _start);
}
private:
high_resolution_clock::time_point _start;
};
// Timer code end
// Cmd redirection code start
/*
//
//Credit goes to some guys from StackOverflow for directions and Randor from CodeProject for base code
//
*/
struct _JOBWRAPPER
{
HANDLE hJob;
_JOBWRAPPER() : hJob(NULL) {}
~_JOBWRAPPER() { if (this->hJob != NULL) CloseHandle(hJob); }
operator HANDLE() const { return this->hJob; }
}hJob;
typedef void(*TextOutFunction)(LPCSTR);
struct _THREADARGUMENTS
{
HANDLE hOutRead;
clock_t stTimeout;
LPCSTR pchBreakText;
TextOutFunction Function;
bool bGotInfo;
_THREADARGUMENTS() : bGotInfo(false), hOutRead(NULL), stTimeout(NULL), pchBreakText(nullptr), Function(nullptr) {}
};
void ReadCMDThread(_THREADARGUMENTS* Arguments)
{
if (Arguments->hOutRead != NULL)
{
UINT CheckForAnyResponseOnLoop = 5, CurrentLoop = 0;
clock_t ScanInterval = 50;
DWORD dwAvailable = 0;
DWORD bytesRead = 0;
CHAR szOut[4096] = { 0 };
if (Arguments->stTimeout == 0)
{
while (true)
{
CurrentLoop++;
PeekNamedPipe(Arguments->hOutRead, szOut, sizeof(szOut), &bytesRead, &dwAvailable, NULL);
if (0 != bytesRead)
{
if (ReadFile(Arguments->hOutRead, szOut, sizeof(szOut), &bytesRead, NULL))
Arguments->bGotInfo = true;
Arguments->Function(szOut);
if (Arguments->pchBreakText != nullptr && Arguments->pchBreakText != "" && strstr(szOut, Arguments->pchBreakText) != nullptr)
break;
memset(szOut, '\0', sizeof(char) * 4096);
}
if (CheckForAnyResponseOnLoop == CurrentLoop && Arguments->pchBreakText == "")
break;
std::this_thread::sleep_for((std::chrono::milliseconds)ScanInterval);
}
}
else
{
Timer timer(true);
while (timer.Elapsed() < (std::chrono::milliseconds)Arguments->stTimeout)
{
CurrentLoop++;
PeekNamedPipe(Arguments->hOutRead, szOut, sizeof(szOut), &bytesRead, &dwAvailable, NULL);
if (0 != bytesRead)
{
if (ReadFile(Arguments->hOutRead, szOut, sizeof(szOut), &bytesRead, NULL))
Arguments->bGotInfo = true;
Arguments->Function(szOut);
timer.Reset();
if (Arguments->pchBreakText != nullptr && Arguments->pchBreakText != "" && strstr(szOut, Arguments->pchBreakText) != nullptr)
break;
memset(szOut, '\0', sizeof(char) * 4096);
}
if (CheckForAnyResponseOnLoop == CurrentLoop && Arguments->pchBreakText == "")
break;
std::this_thread::sleep_for((std::chrono::milliseconds)ScanInterval);
}
}
}
}
class CMDREDIRECTION{
private:
HANDLE hInRead, hInWrite, hOutRead, hOutWrite;
PROCESS_INFORMATION pi;
STARTUPINFO si;
SECURITY_ATTRIBUTES sa;
TextOutFunction CustomFunction;
public:
CMDREDIRECTION(TextOutFunction Function) : hInRead(NULL), hInWrite(NULL), hOutRead(NULL),
hOutWrite(NULL), CustomFunction(Function) {}
~CMDREDIRECTION(){
if (hInRead != NULL)
CloseHandle(hInRead);
if (hInWrite != NULL)
CloseHandle(hInWrite);
if (hOutRead != NULL)
CloseHandle(hOutRead);
if (hOutWrite != NULL)
CloseHandle(hOutWrite);
}
DWORD WriteToCmd(LPSTR pchString, bool PressEnter = false)
{
DWORD dwWritten = 0;
size_t GivenStringLength = strlen(pchString);
LPSTR TemporaryString = pchString;
bool bSuccess = false;
if (GivenStringLength != 0)
{
if (PressEnter)
{
size_t StringSize = GivenStringLength + 2;
TemporaryString = new CHAR[StringSize];
for (size_t i = 0; i < GivenStringLength; i++)
TemporaryString[i] = pchString[i];
TemporaryString[StringSize - 2] = '\n';
TemporaryString[StringSize - 1] = '\0';
bSuccess = (WriteFile(hInWrite, TemporaryString, strlen(TemporaryString), &dwWritten, NULL) && dwWritten);
delete[] TemporaryString;
}
else
bSuccess = (WriteFile(hInWrite, TemporaryString, strlen(TemporaryString), &dwWritten, NULL) && dwWritten);
}
return bSuccess;
}
bool GetAnswer(clock_t stTimeout, LPCSTR pchBreakText)
{
_THREADARGUMENTS Arguments;
Arguments.hOutRead = hOutRead;
Arguments.pchBreakText = pchBreakText;
Arguments.stTimeout = stTimeout;
Arguments.Function = CustomFunction;
std::thread CMDWatcher(ReadCMDThread, &Arguments);
CMDWatcher.join();
return Arguments.bGotInfo;
}
bool WriteToCmdAndWaitForAnswer(LPSTR pchString, clock_t stTimeout, LPCSTR pchBreakText, bool PressEnter = false)
{
if (WriteToCmd(pchString, PressEnter))
{
return (GetAnswer(stTimeout, pchBreakText));
}
else
{
return false;
}
}
bool Start()
{
if (hJob.hJob == NULL)
{
hJob.hJob = CreateJobObject(NULL, NULL);
if (hJob.hJob != NULL)
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli = { 0 };
jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
if (!SetInformationJobObject((HANDLE)hJob, JobObjectExtendedLimitInformation, &jeli, sizeof(jeli)))
{
return false;
}
}
else
{
return false;
}
}
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
CreatePipe(&hInRead, &hInWrite, &sa, 0);
CreatePipe(&hOutRead, &hOutWrite, &sa, 0);
ZeroMemory(&si, sizeof(si));
GetStartupInfo(&si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdOutput = hOutWrite;
si.hStdError = hOutWrite;
si.hStdInput = hInRead;
si.wShowWindow = SW_HIDE;
TCHAR Path[MAX_PATH] = { 0 };
GetSystemDirectory(Path, MAX_PATH);
_tcscat_s(Path, TEXT("\\cmd.exe"));
if (CreateProcess(Path, NULL, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi))
{
BOOL bResult = AssignProcessToJobObject(hJob, pi.hProcess);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return (bResult != 0);
}
else
{
return false;
}
}
};
// Cmd redirection code end
// TString code start
#ifdef UNICODE
#define TCat TCatW
#define TString _TString<WCHAR>
#else
#define TCat TCatA
#define TString _TString<CHAR>
#endif
struct AnyString
{
PVOID String;
bool bWide;
AnyString(LPSTR String)
{
this->String = String;
bWide = false;
}
AnyString(LPWSTR String)
{
this->String = String;
bWide = true;
}
operator LPSTR() { return (LPSTR)String; }
operator LPSTR() const { return (LPSTR)String; }
operator LPWSTR() { return (LPWSTR)String; }
operator LPWSTR() const { return (LPWSTR)String; }
};
template<class T>
class _TString
{
friend void SeAnyString(LPSTR String, _TString<CHAR> &TempString);
T *String;
size_t size;
void free()
{
if (String != nullptr && size != 0)
{
delete[] String;
String = nullptr;
size = 0;
}
}
_TString<CHAR> ToCHAR(LPWSTR wch)
{
_TString<CHAR> TempString;
LPSTR Buffer = nullptr;
size_t size = wcslen(wch),
realsize = size + 1;
if (size != 0)
{
Buffer = new CHAR[realsize];
wcstombs_s(nullptr, Buffer, realsize, wch, size);
TempString.SetAllocatedString(Buffer, size);
}
return TempString;
}
_TString<WCHAR> ToWCHAR(LPSTR ch)
{
_TString<WCHAR> TempString;
LPWSTR Buffer = nullptr;
size_t size = strlen(ch),
realsize = size + 1;
if (size != 0)
{
Buffer = new WCHAR[realsize];
mbstowcs_s(nullptr, Buffer, realsize, ch, size);
TempString.SetAllocatedString(Buffer, size);
}
return TempString;
}
public:
_TString(T *String)
{
free();
if (typeid(T) == typeid(CHAR))
{
size = strlen(String);
if (size != 0)
{
this->String = new T[size + 1];
for (size_t i = 0; i < size; i++)
this->String[i] = String[i];
this->String[size] = '\0';
}
}
else if (typeid(T) == typeid(WCHAR))
{
size = wcslen(String);
if (size != 0)
{
this->String = new T[size + 1];
for (size_t i = 0; i < size; i++)
this->String[i] = String[i];
this->String[size] = L'\0';
}
}
}
_TString() : String(nullptr), size(0) {}
~_TString() { free(); }
_TString(_TString&& OldTempStr)
{
this->String = OldTempStr.String;
this->size = OldTempStr.size;
OldTempStr.size = 0;
OldTempStr.String = nullptr;
}
_TString& operator=(_TString&& OldTempStr)
{
this->String = OldTempStr.String;
this->size = OldTempStr.size;
OldTempStr.size = 0;
OldTempStr.String = nullptr;
return *this;
}
operator T*() const { return String; }
operator T*() { return String; }
T& operator[] (size_t i) { return String[i]; }
void SetAllocatedString(T *String, size_t size)
{
free();
this->String = String;
this->size = size;
}
void join(LPWSTR StringToJoin)
{
join(AnyString(StringToJoin));
}
void join(LPSTR StringToJoin)
{
join(AnyString(StringToJoin));
}
void join(AnyString StringToJoin)
{
if (typeid(T) == typeid(CHAR))
{
size_t length = 0;
_TString<CHAR> TempString;
LPSTR StringLiteral = nullptr;
if (StringToJoin.bWide)
{
TempString = ToCHAR(StringToJoin);
StringLiteral = TempString;
}
else
{
StringLiteral = StringToJoin;
}
if (StringLiteral != nullptr)
length = strlen(StringLiteral);
if (length != 0)
{
size_t newsize = size + length, realsize = newsize + 1;
T *Buffer = new T[realsize];
for (size_t i = 0; i < size; i++)
Buffer[i] = String[i];
for (size_t i = size, j = 0; i < newsize; i++, j++)
Buffer[i] = StringLiteral[j];
Buffer[newsize] = '\0';
free();
size = newsize;
String = Buffer;
}
}
else if (typeid(T) == typeid(WCHAR))
{
size_t length = 0;
_TString<WCHAR> TempString;
LPWSTR StringLiteral = nullptr;
if (StringToJoin.bWide)
{
StringLiteral = StringToJoin;
}
else
{
TempString = ToWCHAR(StringToJoin);
StringLiteral = TempString;
}
if (StringLiteral != nullptr)
length = wcslen(StringLiteral);
if (length != 0)
{
size_t newsize = size + length, realsize = newsize + 1;
T *Buffer = new T[realsize];
for (size_t i = 0; i < size; i++)
Buffer[i] = String[i];
for (size_t i = size, j = 0; i < newsize; i++, j++)
Buffer[i] = StringLiteral[j];
Buffer[newsize] = L'\0';
free();
size = newsize;
String = Buffer;
}
}
}
size_t GetSize() { return size; }
T* GetString() { return String; }
};
_TString<CHAR> TCatA(std::initializer_list<AnyString> list)
{
_TString<CHAR> String;
for (auto iterator = list.begin(), end = list.end(); iterator != end; ++iterator)
String.join(*iterator);
return String;
}
_TString<WCHAR> TCatW(std::initializer_list<AnyString> list)
{
_TString<WCHAR> String;
for (auto iterator = list.begin(), end = list.end(); iterator != end; ++iterator)
String.join(*iterator);
return String;
}
// TString code end
// Main code start
#define EXTENSION_NAME YOUR_EXTENSION_NAME //"my-extension" in ANSI
void WriteToOutputWindow(LPCSTR Text) { OutputDebugStringA(Text); }
void GetProjectDirectory(TString &Path)
{
TCHAR MaxPath[MAX_PATH] = { 0 };
GetModuleFileName(NULL, MaxPath, MAX_PATH);
for (int i = _tcslen(MaxPath), ch = 0; i > 0; i--)
{
if (MaxPath[i] == TEXT('\\') && ++ch == 2)
break;
else
MaxPath[i] = TEXT('\0');
}
Path.join(MaxPath);
}
void GetDataDirectory(TString &Path)
{
GetProjectDirectory(Path);
TCHAR TempBuffer[MAX_PATH] = { 0 }, FinalBuffer[MAX_PATH] = { 0 };
for (size_t i = Path.GetSize() - 1, ch = 0, j = 0; i > 0; i--, j++)
{
if (Path[i] == TEXT('\\') && ++ch == 2)
break;
else
TempBuffer[j] = Path[i];
}
for (size_t i = _tcslen(TempBuffer), j = 0; i > 0; i--, j++)
FinalBuffer[j] = TempBuffer[i - 1];
Path.join(FinalBuffer);
}
bool Restart()
{
int msgboxID = MessageBox(NULL, TEXT("Firefox has been closed. Save changes and press \"Yes\" to run again."), TEXT("Run again?"), MB_YESNO | MB_ICONQUESTION);
switch (msgboxID)
{
case IDYES:
return true;
case IDNO:
return false;
}
}
int WINAPI _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrev, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow)
{
CMDREDIRECTION Window(WriteToOutputWindow);
TString ExtensionDir;
TString DataDir;
if (Window.Start())
{
GetProjectDirectory(ExtensionDir);
GetDataDirectory(DataDir);
ExtensionDir.join(TEXT("Firefox SDK\\"));
if (!PathIsDirectory(ExtensionDir))
Window.WriteToCmdAndWaitForAnswer(TCatA({ "mkdir \"", ExtensionDir.GetString(), "\"" }), 0, "", true);
if (PathIsDirectoryEmpty(ExtensionDir))
{
MessageBox(NULL, TCat({ TEXT("Firefox SDK directory is empty, please copy SDK files to this directory: "), ExtensionDir.GetString() }), TEXT("Failure!"), MB_ICONINFORMATION);
return EXIT_FAILURE;
}
Window.WriteToCmdAndWaitForAnswer(TCatA({ "cd ", ExtensionDir.GetString() }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer("bin\\activate", 0, "", true);
ExtensionDir.join(TCat({ TEXT(EXTENSION_NAME), TEXT("\\") }));
if (!PathIsDirectory(ExtensionDir))
Window.WriteToCmdAndWaitForAnswer(TCatA({ "mkdir ", EXTENSION_NAME }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "cd ", EXTENSION_NAME }), 0, "", true);
if (PathIsDirectoryEmpty(ExtensionDir))
Window.WriteToCmdAndWaitForAnswer("cfx init", 0, "", true);
do
{
/*
Window.WriteToCmdAndWaitForAnswer(TCatA({ "cd ", DataDir.GetString() }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"main.js\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\lib\\\" /Y" }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"*.js\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\data\\\" /Y /EXCLUDE:exclude.txt" }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"*.html\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\data\\\" /Y" }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"*.png\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\data\\\" /Y" }), 0, "", true);
Window.WriteToCmdAndWaitForAnswer(TCatA({ "XCOPY \"*.css\" \"", ExtensionDir.GetString(), TEXT(EXTENSION_NAME), "\\data\\\" /Y" }), 0, "", true);
*/
Window.WriteToCmdAndWaitForAnswer("cfx run --profiledir=\"./dir\"", 0, "Program terminated successfully.", true);
} while (Restart());
}
return EXIT_SUCCESS;
}
// Main code end

Map Isn't Returning Correct Numbers

I have a map that is acting up and not returning the correct number. It did then it didn't, now it's just not returning. Any help is appreciated. Thank you.
struct file_data
{
std::wstring sLastAccessTime;
__int64 nFileSize ;
};
int GetFileList(const wchar_t *searchkey, std::map<std::wstring, file_data> &map)
{
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile(searchkey,&fd);
if(h == INVALID_HANDLE_VALUE)
{
return 0; // no files found
}
while(1)
{
wchar_t buf[128];
FILETIME ft = fd.ftLastWriteTime;
SYSTEMTIME sysTime;
FileTimeToSystemTime(&ft, &sysTime);
wsprintf(buf, L"%d-%02d-%02d",sysTime.wYear, sysTime.wMonth, sysTime.wDay);
file_data filedata;
filedata.sLastAccessTime= buf;
filedata.nFileSize = (((__int64)fd.nFileSizeHigh) << 32) + fd.nFileSizeLow;
map[fd.cFileName]= filedata;
if (FindNextFile(h, &fd) == FALSE)
break;
}
return map.size();
}
int main()
{
std::map<std::wstring, file_data> map;
int count = GetFileList(L"C:\\Users\\DS\\Downloads\\*.pdf", map);
int count1 = GetFileList(L"C:\\Users\\DS\\Downloads\\*.txt", map);
int count2 = GetFileList(L"C:\\Users\\DS\\Downloads\\*.jpg", map);
for(std::map<std::wstring, file_data>::const_iterator it = map.begin(); it != map.end(); ++it)
{
if (count2 != 0)
{
printf("\n How Many: %i \n", count2);
}
else
{
printf ("%s \n", "Nothing");
}
return 0;
}
}
Note that GetFileList() returns the number of items in the map.
In your implementation it is cumulative. Maybe you want to clear the map between consecutive calls to GetFileList().
OK found the solution. This is it.
GetFileList(L"C:\\Users\\DS\\Downloads\\*.pdf", map);
GetFileList(L"C:\\Users\\DS\\Downloads\\*.txt", map);
GetFileList(L"C:\\Users\\DS\\Downloads\\*.jpg", map);
if( map.size() > 0
then...........

GdipCreateBitmapFromStream change of contract on Windows 7?

We have a perfectly functional app that just broke on Windows 7 because (the GDI+ primitive) GdipCreateBitmapFromStream refuses JPEG images presented to it (without problem on XP and even Vista).
We don't directly call GDI+, we call the documented ATL CImage class, and it calls that, and gets the error.
It's our own OLE stream implementation.
Has anyone seen a way around this?
Here is a complete test case:
#include <atlbase.h>
#include <atlimage.h>
#include <gdiplus.h>
#include <time.h>
#include <sys/stat.h>
// GSMemoryStream.h : Declaration of the GSMemoryStream
/* No ATL or class factory support is needed here. You get one of these via "new", with zero reference count...
Image.Load(IStreamPtr(new GSMemoryStream(ptr, len));
and the smart pointer will provoke its deletion at the right time....
*/
// GSMemoryStream
class GSMemoryStream :
public IStream
{
private:
ULONG m_Length;
ULONG m_CurPtr;
PBYTE m_Base;
int m_rc;
public:
GSMemoryStream(PBYTE _p, DWORD _len) {
m_Length = _len;
m_CurPtr = 0;
m_Base = _p;
m_rc = 0;
}
GSMemoryStream () {
m_Length = 0;
m_CurPtr = 0;
m_Base = NULL;
m_rc = 0;
}
STDMETHODIMP Read(void *,ULONG,ULONG *);
STDMETHODIMP Write(const void *,ULONG,ULONG *) {return E_FAIL;}
STDMETHODIMP Seek(LARGE_INTEGER,DWORD,ULARGE_INTEGER *);
STDMETHODIMP SetSize(ULARGE_INTEGER) {return E_FAIL;}
STDMETHODIMP CopyTo(IStream *,ULARGE_INTEGER,ULARGE_INTEGER *,ULARGE_INTEGER *);
STDMETHODIMP Commit(DWORD) {return S_OK;}
STDMETHODIMP Revert(void) {return S_OK;}
STDMETHODIMP LockRegion(ULARGE_INTEGER,ULARGE_INTEGER,DWORD) {return S_OK;}
STDMETHODIMP UnlockRegion(ULARGE_INTEGER,ULARGE_INTEGER,DWORD) {return S_OK;}
STDMETHODIMP Stat(STATSTG *,DWORD);
STDMETHODIMP Clone(IStream ** ) {return E_FAIL;}
STDMETHODIMP QueryInterface(const IID & iid,void ** d) throw() {
if (IsEqualGUID(iid, IID_IUnknown) || IsEqualGUID (iid, __uuidof(IStream))) {
*d = (PVOID)this;
AddRef();
return S_OK;
}
return E_FAIL;
}
ULONG STDMETHODCALLTYPE AddRef(void) throw() {
m_rc++;
return S_OK;
}
ULONG STDMETHODCALLTYPE Release(void) throw() {
if (--m_rc == 0)
delete this; // can never go negative, because the m_rc won't be around any more once it is 0.
// so it's not even meaningful to test for it and breakpoint or throw.
return S_OK;
}
};
// CGSMemoryStream
STDMETHODIMP GSMemoryStream::Read(void * p,ULONG n, ULONG * pNread) {
ATLTRACE(L"GSMS$Read p %p bufct %d m_curptr %d\r\n", p, n, m_CurPtr);
if ((n + m_CurPtr) > m_Length)
n = m_Length - m_CurPtr;
memcpy(p, m_Base + m_CurPtr, n);
if (pNread)
*pNread = n;
m_CurPtr += n;
ATLTRACE(L"GSMS$Read(final) n %d m_CurPtr %d\r\n", n, m_CurPtr);
return S_OK;
}
STDMETHODIMP GSMemoryStream::Seek(LARGE_INTEGER pos,DWORD type,ULARGE_INTEGER * newpos) {
LONG lpos = (LONG)pos.LowPart;
ATLTRACE(L"GSMS$Seek type %d lpos %d m_CurPtr %d\r\n", type, lpos, m_CurPtr);
switch (type) {
case STREAM_SEEK_SET:
if (lpos < 0 || lpos > (LONG) m_Length)
return E_POINTER;
m_CurPtr = (ULONG)lpos;
break;
case STREAM_SEEK_CUR:
if (lpos + m_CurPtr < 0 || lpos + m_CurPtr > m_Length)
return E_POINTER;
m_CurPtr += lpos;
break;
case STREAM_SEEK_END:
if (lpos > 0)
lpos = -lpos;
if (lpos + m_Length < 0)
return E_POINTER;
m_CurPtr = m_Length + lpos;
break;
default:
return E_FAIL;
}
ATLTRACE(L"GSMS$Seek end m_CurPtr %d\r\n", m_CurPtr);
if (newpos) {
newpos->HighPart = 0;
newpos->LowPart = m_CurPtr;
}
return S_OK;
}
STDMETHODIMP GSMemoryStream::CopyTo(IStream * pstm,ULARGE_INTEGER cb,ULARGE_INTEGER * pNread,ULARGE_INTEGER * pNwritten){
ATLTRACE("GSMS$CopyTo\r\n");
if (cb.HighPart)
return E_INVALIDARG;
ULONG n = cb.LowPart;
if ((n + m_CurPtr) > m_Length)
n = m_Length - m_CurPtr;
ULONG nwritten = 0;
HRESULT hr = pstm->Write(m_Base+m_CurPtr, n, &nwritten);
if (nwritten < n)
nwritten = n;
if (pNread) {
pNread->HighPart = 0;
pNread->LowPart = n;
}
if (pNwritten) {
pNwritten->HighPart = 0;
pNwritten->LowPart = nwritten;
}
m_CurPtr += n;
return hr;
}
STDMETHODIMP GSMemoryStream::Stat(STATSTG * ps,DWORD krazyflag) {
ATLTRACE(L"GSMS$Stat kf %d\r\n", krazyflag);
memset(ps, 0, sizeof(STATSTG));
ps->type = STGTY_STREAM;
ps->cbSize.LowPart = m_Length;
ps->cbSize.HighPart = 0;
#if 0
ps->mtime = (DWORD)time(NULL);
ps->ctime = (DWORD)time(NULL);
ps->atime = (DWORD)time(NULL);
#endif
return S_OK;
}
int main (int argc, char ** argv) {
if (argc < 2) {
fprintf(stderr, "Need image file pathname\n");
exit(2);
}
struct _stat SSTAT;
const char* fn = argv[1];
int failed = _stat(fn, &SSTAT);
if (failed) {
fprintf(stderr, "Can't open file: %s\n", fn);
exit(3);
}
size_t len = SSTAT.st_size;
printf ("Len = %d\n", len);
FILE* f = fopen(fn, "rb");
unsigned char * buf = new unsigned char [len];
size_t got = fread (buf, 1, len, f);
printf ("Got = %d\n", got);
fclose(f);
CoInitialize(NULL);
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
GSMemoryStream G(buf, len);
CImage cim;
HRESULT hr = cim.Load(&G);
printf("HRESULT = 0x%08X\n", hr);
delete [] buf;
CoUninitialize();
return 0;
}
Have you tried using the documented Bitmap object instead of using the undocumented GDI+ entrypoints?
Further research reveals that W7 queries an additional optional interface on the stream, and it's essential to return E_NOINTERFACE instead of E_NOTIMPL for it.

Resources