1 //**********************************************************************************
2 //EncryptPad Copyright 2016 Evgeny Pokhilko
3 //<http://www.evpo.net/encryptpad>
4 //
5 //This file is part of EncryptPad
6 //
7 //EncryptPad is free software: you can redistribute it and/or modify
8 //it under the terms of the GNU General Public License as published by
9 //the Free Software Foundation, either version 2 of the License, or
10 //(at your option) any later version.
11 //
12 //EncryptPad is distributed in the hope that it will be useful,
13 //but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //GNU General Public License for more details.
16 //
17 //You should have received a copy of the GNU General Public License
18 //along with EncryptPad.  If not, see <http://www.gnu.org/licenses/>.
19 //**********************************************************************************
20 #if defined(__MINGW__) || defined(__MINGW32__)
21 
22 #include "win_file_reader.h"
23 #include <fstream>
24 
25 #include "wchar.h"
26 #include "stringapiset.h"
27 #include "windows.h"
28 #include "userenv.h"
29 #include "io.h"
30 #include "fcntl.h"
31 
32 namespace
33 {
Multi2Wide(const std::string & multi,std::wstring & wide)34     void Multi2Wide(const std::string &multi, std::wstring &wide)
35     {
36         wide.clear();
37         int len = MultiByteToWideChar(CP_UTF8, 0, multi.c_str(), -1,
38                 nullptr, 0);
39         if(!len)
40             return;
41 
42         wide.resize(len - 1, 0);
43         MultiByteToWideChar(CP_UTF8, 0, multi.data(), multi.size(),
44                 &wide[0], wide.size());
45     }
46 
Wide2Multi(const std::wstring & wide,std::string & multi)47     void Wide2Multi(const std::wstring &wide, std::string &multi)
48     {
49         multi.clear();
50 
51         if(wide.empty())
52             return;
53 
54         int len = WideCharToMultiByte(CP_UTF8, 0, &wide[0], static_cast<int>(wide.size()),
55                 nullptr, 0, nullptr, nullptr);
56 
57         multi.resize(len - 1, 0);
58 
59         WideCharToMultiByte(CP_UTF8, 0, &wide[0], static_cast<int>(wide.size()),
60                 &multi[0], len, nullptr, nullptr);
61     }
62 }
63 
64 namespace EncryptPad
65 {
ExpandVariablesWin(const std::string & path)66     std::string ExpandVariablesWin(const std::string &path)
67     {
68         std::wstring wide;
69         Multi2Wide(path, wide);
70 
71         std::wstring buffer;
72         buffer.resize(MAX_PATH);
73         DWORD size = ExpandEnvironmentStringsW(wide.c_str(), &buffer[0], buffer.size());
74         while(size == buffer.size())
75         {
76             buffer.resize(buffer.size() * 2);
77             size = ExpandEnvironmentStringsW(wide.c_str(), &buffer[0], buffer.size());
78         }
79         buffer.resize(size);
80         wide = buffer;
81         std::string multi;
82         Wide2Multi(wide, multi);
83         return multi;
84     }
85 
OpenInputWin(const std::string & file_name)86     FileHndl OpenInputWin(const std::string &file_name)
87     {
88         if(file_name == "-")
89         {
90             if(_setmode(fileno(stdin), _O_BINARY) == -1)
91                 return FileHndl();
92 
93             return FileHndl(stdin);
94         }
95 
96         std::wstring wide;
97         Multi2Wide(file_name, wide);
98         return FileHndl(_wfopen(wide.data(), L"rb"));
99     }
100 
OpenOutputWin(const std::string & file_name)101     FileHndl OpenOutputWin(const std::string &file_name)
102     {
103         if(file_name == "-")
104         {
105             if(_setmode(fileno(stdout), _O_BINARY) == -1)
106                 return FileHndl();
107 
108             return FileHndl(stdout);
109         }
110 
111         std::wstring wide;
112         Multi2Wide(file_name, wide);
113         return FileHndl(_wfopen(wide.data(), L"wb"));
114     }
115 
RemoveFileWin(const std::string & file_name)116     bool RemoveFileWin(const std::string &file_name)
117     {
118         std::wstring wide;
119         Multi2Wide(file_name, wide);
120         return _wremove(wide.data()) == 0;
121     }
122 
WinFTell(FileHndl & file)123     stream_length_type WinFTell(FileHndl &file)
124     {
125 		return _ftelli64(file.get());
126     }
127 
WinFSeek(FileHndl & file,stream_length_type offset,int origin)128     int WinFSeek(FileHndl &file, stream_length_type offset, int origin)
129     {
130 		return _fseeki64(file.get(), offset, origin);
131     }
132 }
133 #endif
134