source: XMLIO_V2/external/src/POCO/Foundation.save/File_WIN32U.cpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 9.6 KB
Line 
1//
2// File_WIN32U.cpp
3//
4// $Id: //poco/1.3/Foundation/src/File_WIN32U.cpp#11 $
5//
6// Library: Foundation
7// Package: Filesystem
8// Module:  File
9//
10// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// Permission is hereby granted, free of charge, to any person or organization
14// obtaining a copy of the software and accompanying documentation covered by
15// this license (the "Software") to use, reproduce, display, distribute,
16// execute, and transmit the Software, and to prepare derivative works of the
17// Software, and to permit third-parties to whom the Software is furnished to
18// do so, all subject to the following:
19//
20// The copyright notices in the Software and this entire statement, including
21// the above license grant, this restriction and the following disclaimer,
22// must be included in all copies of the Software, in whole or in part, and
23// all derivative works of the Software, unless such copies or derivative
24// works are solely in the form of machine-executable object code generated by
25// a source language processor.
26//
27// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33// DEALINGS IN THE SOFTWARE.
34//
35
36
37#include "Poco/File_WIN32U.h"
38#include "Poco/Exception.h"
39#include "Poco/String.h"
40#include "Poco/UnicodeConverter.h"
41#include "Poco/UnWindows.h"
42
43
44namespace Poco {
45
46
47class FileHandle
48{
49public:
50        FileHandle(const std::string& path, const std::wstring& upath, DWORD access, DWORD share, DWORD disp)
51        {
52                _h = CreateFileW(upath.c_str(), access, share, 0, disp, 0, 0);
53                if (_h == INVALID_HANDLE_VALUE)
54                {
55                        FileImpl::handleLastErrorImpl(path);
56                }
57        }
58       
59        ~FileHandle()
60        {
61                if (_h != INVALID_HANDLE_VALUE) CloseHandle(_h);
62        }
63       
64        HANDLE get() const
65        {
66                return _h;
67        }
68       
69private:
70        HANDLE _h;
71};
72
73
74FileImpl::FileImpl()
75{
76}
77
78
79FileImpl::FileImpl(const std::string& path): _path(path)
80{
81        std::string::size_type n = _path.size();
82        if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
83        {
84                _path.resize(n - 1);
85        }
86        UnicodeConverter::toUTF16(_path, _upath);
87}
88
89
90FileImpl::~FileImpl()
91{
92}
93
94
95void FileImpl::swapImpl(FileImpl& file)
96{
97        std::swap(_path, file._path);
98        std::swap(_upath, file._upath);
99}
100
101
102void FileImpl::setPathImpl(const std::string& path)
103{
104        _path = path;
105        std::string::size_type n = _path.size();
106        if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
107        {
108                _path.resize(n - 1);
109        }
110        UnicodeConverter::toUTF16(_path, _upath);
111}
112
113
114bool FileImpl::existsImpl() const
115{
116        poco_assert (!_path.empty());
117
118        DWORD attr = GetFileAttributesW(_upath.c_str());
119        if (attr == 0xFFFFFFFF)
120        {
121                switch (GetLastError())
122                {
123                case ERROR_FILE_NOT_FOUND:
124                case ERROR_PATH_NOT_FOUND:
125                case ERROR_NOT_READY:
126                case ERROR_INVALID_DRIVE:
127                        return false;
128                default:
129                        handleLastErrorImpl(_path);
130                }
131        }
132        return true;
133}
134
135
136bool FileImpl::canReadImpl() const
137{
138        poco_assert (!_path.empty());
139       
140        DWORD attr = GetFileAttributesW(_upath.c_str());
141        if (attr == 0xFFFFFFFF)
142        {
143                switch (GetLastError())
144                {
145                case ERROR_ACCESS_DENIED:
146                        return false;
147                default:
148                        handleLastErrorImpl(_path);
149                }
150        }
151        return true;
152}
153
154
155bool FileImpl::canWriteImpl() const
156{
157        poco_assert (!_path.empty());
158       
159        DWORD attr = GetFileAttributesW(_upath.c_str());
160        if (attr == 0xFFFFFFFF)
161                handleLastErrorImpl(_path);
162        return (attr & FILE_ATTRIBUTE_READONLY) == 0;
163}
164
165
166bool FileImpl::canExecuteImpl() const
167{
168        Path p(_path);
169        return icompare(p.getExtension(), "exe") == 0;
170}
171
172
173bool FileImpl::isFileImpl() const
174{
175        return !isDirectoryImpl() && !isDeviceImpl();
176}
177
178
179bool FileImpl::isDirectoryImpl() const
180{
181        poco_assert (!_path.empty());
182
183        DWORD attr = GetFileAttributesW(_upath.c_str());
184        if (attr == 0xFFFFFFFF)
185                handleLastErrorImpl(_path);
186        return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
187}
188
189
190bool FileImpl::isLinkImpl() const
191{
192        return false;
193}
194
195
196bool FileImpl::isDeviceImpl() const
197{
198        poco_assert (!_path.empty());
199
200        FileHandle fh(_path, _upath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
201        DWORD type = GetFileType(fh.get());
202        if (type == FILE_TYPE_CHAR)
203                return true;
204        else if (type == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR)
205                handleLastErrorImpl(_path);
206        return false;
207}
208
209
210bool FileImpl::isHiddenImpl() const
211{
212        poco_assert (!_path.empty());
213
214        DWORD attr = GetFileAttributesW(_upath.c_str());
215        if (attr == 0xFFFFFFFF)
216                handleLastErrorImpl(_path);
217        return (attr & FILE_ATTRIBUTE_HIDDEN) != 0;
218}
219
220
221Timestamp FileImpl::createdImpl() const
222{
223        poco_assert (!_path.empty());
224
225        WIN32_FILE_ATTRIBUTE_DATA fad;
226        if (GetFileAttributesExW(_upath.c_str(), GetFileExInfoStandard, &fad) == 0) 
227                handleLastErrorImpl(_path);
228        return Timestamp::fromFileTimeNP(fad.ftCreationTime.dwLowDateTime, fad.ftCreationTime.dwHighDateTime);
229}
230
231
232Timestamp FileImpl::getLastModifiedImpl() const
233{
234        poco_assert (!_path.empty());
235
236        WIN32_FILE_ATTRIBUTE_DATA fad;
237        if (GetFileAttributesExW(_upath.c_str(), GetFileExInfoStandard, &fad) == 0) 
238                handleLastErrorImpl(_path);
239        return Timestamp::fromFileTimeNP(fad.ftLastWriteTime.dwLowDateTime, fad.ftLastWriteTime.dwHighDateTime);
240}
241
242
243void FileImpl::setLastModifiedImpl(const Timestamp& ts)
244{
245        poco_assert (!_path.empty());
246
247        UInt32 low;
248        UInt32 high;
249        ts.toFileTimeNP(low, high);
250        FILETIME ft;
251        ft.dwLowDateTime  = low;
252        ft.dwHighDateTime = high;
253        FileHandle fh(_path, _upath, FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
254        if (SetFileTime(fh.get(), 0, &ft, &ft) == 0)
255                handleLastErrorImpl(_path);
256}
257
258
259FileImpl::FileSizeImpl FileImpl::getSizeImpl() const
260{
261        poco_assert (!_path.empty());
262
263        WIN32_FILE_ATTRIBUTE_DATA fad;
264        if (GetFileAttributesExW(_upath.c_str(), GetFileExInfoStandard, &fad) == 0) 
265                handleLastErrorImpl(_path);
266        LARGE_INTEGER li;
267        li.LowPart  = fad.nFileSizeLow;
268        li.HighPart = fad.nFileSizeHigh;
269        return li.QuadPart;
270}
271
272
273void FileImpl::setSizeImpl(FileSizeImpl size)
274{
275        poco_assert (!_path.empty());
276
277        FileHandle fh(_path, _upath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
278        LARGE_INTEGER li;
279        li.QuadPart = size;
280        if (SetFilePointer(fh.get(), li.LowPart, &li.HighPart, FILE_BEGIN) == -1)
281                handleLastErrorImpl(_path);
282        if (SetEndOfFile(fh.get()) == 0) 
283                handleLastErrorImpl(_path);
284}
285
286
287void FileImpl::setWriteableImpl(bool flag)             
288{
289        poco_assert (!_path.empty());
290
291        DWORD attr = GetFileAttributesW(_upath.c_str());
292        if (attr == -1)
293                handleLastErrorImpl(_path);
294        if (flag)
295                attr &= ~FILE_ATTRIBUTE_READONLY;
296        else
297                attr |= FILE_ATTRIBUTE_READONLY;
298        if (SetFileAttributesW(_upath.c_str(), attr) == 0)
299                handleLastErrorImpl(_path);
300}
301
302
303void FileImpl::setExecutableImpl(bool flag)
304{
305        // not supported
306}
307
308
309void FileImpl::copyToImpl(const std::string& path) const
310{
311        poco_assert (!_path.empty());
312
313        std::wstring upath;
314        UnicodeConverter::toUTF16(path, upath);
315        if (CopyFileW(_upath.c_str(), upath.c_str(), FALSE) != 0)
316        {
317                FileImpl copy(path);
318                copy.setWriteableImpl(true);
319        }
320        else handleLastErrorImpl(_path);
321}
322
323
324void FileImpl::renameToImpl(const std::string& path)
325{
326        poco_assert (!_path.empty());
327
328        std::wstring upath;
329        UnicodeConverter::toUTF16(path, upath);
330        if (MoveFileW(_upath.c_str(), upath.c_str()) == 0) 
331                handleLastErrorImpl(_path);
332}
333
334
335void FileImpl::removeImpl()
336{
337        poco_assert (!_path.empty());
338
339        if (isDirectoryImpl())
340        {
341                if (RemoveDirectoryW(_upath.c_str()) == 0) 
342                        handleLastErrorImpl(_path);
343        }
344        else
345        {
346                if (DeleteFileW(_upath.c_str()) == 0)
347                        handleLastErrorImpl(_path);
348        }
349}
350
351
352bool FileImpl::createFileImpl()
353{
354        poco_assert (!_path.empty());
355
356        HANDLE hFile = CreateFileW(_upath.c_str(), GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0);
357        if (hFile != INVALID_HANDLE_VALUE)
358        {
359                CloseHandle(hFile);
360                return true;
361        }
362        else if (GetLastError() == ERROR_FILE_EXISTS)
363                return false;
364        else
365                handleLastErrorImpl(_path);
366        return false;
367}
368
369
370bool FileImpl::createDirectoryImpl()
371{
372        poco_assert (!_path.empty());
373       
374        if (existsImpl() && isDirectoryImpl())
375                return false;
376        if (CreateDirectoryW(_upath.c_str(), 0) == 0)
377                handleLastErrorImpl(_path);
378        return true;
379}
380
381
382void FileImpl::handleLastErrorImpl(const std::string& path)
383{
384        switch (GetLastError())
385        {
386        case ERROR_FILE_NOT_FOUND:
387                throw FileNotFoundException(path);
388        case ERROR_PATH_NOT_FOUND:
389        case ERROR_BAD_NETPATH:
390        case ERROR_CANT_RESOLVE_FILENAME:
391        case ERROR_INVALID_DRIVE:
392                throw PathNotFoundException(path);
393        case ERROR_ACCESS_DENIED:
394                throw FileAccessDeniedException(path);
395        case ERROR_ALREADY_EXISTS:
396        case ERROR_FILE_EXISTS:
397                throw FileExistsException(path);
398        case ERROR_INVALID_NAME:
399        case ERROR_DIRECTORY:
400        case ERROR_FILENAME_EXCED_RANGE:
401        case ERROR_BAD_PATHNAME:
402                throw PathSyntaxException(path);
403        case ERROR_FILE_READ_ONLY:
404                throw FileReadOnlyException(path);
405        case ERROR_CANNOT_MAKE:
406                throw CreateFileException(path);
407        case ERROR_DIR_NOT_EMPTY:
408                throw FileException("directory not empty", path);
409        case ERROR_WRITE_FAULT:
410                throw WriteFileException(path);
411        case ERROR_READ_FAULT:
412                throw ReadFileException(path);
413        case ERROR_SHARING_VIOLATION:
414                throw FileException("sharing violation", path);
415        case ERROR_LOCK_VIOLATION:
416                throw FileException("lock violation", path);
417        case ERROR_HANDLE_EOF:
418                throw ReadFileException("EOF reached", path);
419        case ERROR_HANDLE_DISK_FULL:
420        case ERROR_DISK_FULL:
421                throw WriteFileException("disk is full", path);
422        case ERROR_NEGATIVE_SEEK:
423                throw FileException("negative seek", path);
424        default:
425                throw FileException(path);
426        }
427}
428
429
430} // namespace Poco
Note: See TracBrowser for help on using the repository browser.