source: XMLIO_V2/external/src/POCO/Foundation/File_WIN32.hpp @ 80

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

ajout lib externe

File size: 9.2 KB
Line 
1//
2// File_WIN32.cpp
3//
4// $Id: //poco/1.3/Foundation/src/File_WIN32.cpp#10 $
5//
6// Library: Foundation
7// Package: Filesystem
8// Module:  File
9//
10// Copyright (c) 2004-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_WIN32.h>
38#include <Poco/Exception.h>
39#include <Poco/String.h>
40#include <Poco/UnWindows.h>
41
42
43namespace Poco {
44
45
46class FileHandle
47{
48public:
49        FileHandle(const std::string& path, DWORD access, DWORD share, DWORD disp)
50        {
51                _h = CreateFileA(path.c_str(), access, share, 0, disp, 0, 0);
52                if (_h == INVALID_HANDLE_VALUE)
53                {
54                        FileImpl::handleLastErrorImpl(path);
55                }
56        }
57       
58        ~FileHandle()
59        {
60                if (_h != INVALID_HANDLE_VALUE) CloseHandle(_h);
61        }
62       
63        HANDLE get() const
64        {
65                return _h;
66        }
67       
68private:
69        HANDLE _h;
70};
71
72
73FileImpl::FileImpl()
74{
75}
76
77
78FileImpl::FileImpl(const std::string& path): _path(path)
79{
80        std::string::size_type n = _path.size();
81        if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
82        {
83                _path.resize(n - 1);
84        }
85}
86
87
88FileImpl::~FileImpl()
89{
90}
91
92
93void FileImpl::swapImpl(FileImpl& file)
94{
95        std::swap(_path, file._path);
96}
97
98
99void FileImpl::setPathImpl(const std::string& path)
100{
101        _path = path;
102        std::string::size_type n = _path.size();
103        if (n > 1 && (_path[n - 1] == '\\' || _path[n - 1] == '/') && !((n == 3 && _path[1]==':')))
104        {
105                _path.resize(n - 1);
106        }
107}
108
109
110bool FileImpl::existsImpl() const
111{
112        poco_assert (!_path.empty());
113
114        DWORD attr = GetFileAttributes(_path.c_str());
115        if (attr == 0xFFFFFFFF)
116        {
117                switch (GetLastError())
118                {
119                case ERROR_FILE_NOT_FOUND:
120                case ERROR_PATH_NOT_FOUND:
121                case ERROR_NOT_READY:
122                case ERROR_INVALID_DRIVE:
123                        return false;
124                default:
125                        handleLastErrorImpl(_path);
126                }
127        }
128        return true;
129}
130
131
132bool FileImpl::canReadImpl() const
133{
134        poco_assert (!_path.empty());
135       
136        DWORD attr = GetFileAttributes(_path.c_str());
137        if (attr == 0xFFFFFFFF)
138        {
139                switch (GetLastError())
140                {
141                case ERROR_ACCESS_DENIED:
142                        return false;
143                default:
144                        handleLastErrorImpl(_path);
145                }
146        }
147        return true;
148}
149
150
151bool FileImpl::canWriteImpl() const
152{
153        poco_assert (!_path.empty());
154       
155        DWORD attr = GetFileAttributes(_path.c_str());
156        if (attr == 0xFFFFFFFF)
157                handleLastErrorImpl(_path);
158        return (attr & FILE_ATTRIBUTE_READONLY) == 0;
159}
160
161
162bool FileImpl::canExecuteImpl() const
163{
164        Path p(_path);
165        return icompare(p.getExtension(), "exe") == 0;
166}
167
168
169bool FileImpl::isFileImpl() const
170{
171        return !isDirectoryImpl() && !isDeviceImpl();
172}
173
174
175bool FileImpl::isDirectoryImpl() const
176{
177        poco_assert (!_path.empty());
178
179        DWORD attr = GetFileAttributes(_path.c_str());
180        if (attr == 0xFFFFFFFF)
181                handleLastErrorImpl(_path);
182        return (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
183}
184
185
186bool FileImpl::isLinkImpl() const
187{
188        return false;
189}
190
191
192bool FileImpl::isDeviceImpl() const
193{
194        poco_assert (!_path.empty());
195
196        FileHandle fh(_path, GENERIC_READ, 0, OPEN_EXISTING);
197        DWORD type = GetFileType(fh.get());
198        if (type == FILE_TYPE_CHAR)
199                return true;
200        else if (type == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR)
201                handleLastErrorImpl(_path);
202        return false;
203}
204
205
206bool FileImpl::isHiddenImpl() const
207{
208        poco_assert (!_path.empty());
209
210        DWORD attr = GetFileAttributes(_path.c_str());
211        if (attr == 0xFFFFFFFF)
212                handleLastErrorImpl(_path);
213        return (attr & FILE_ATTRIBUTE_HIDDEN) != 0;
214}
215
216
217Timestamp FileImpl::createdImpl() const
218{
219        poco_assert (!_path.empty());
220
221        WIN32_FILE_ATTRIBUTE_DATA fad;
222        if (GetFileAttributesEx(_path.c_str(), GetFileExInfoStandard, &fad) == 0) 
223                handleLastErrorImpl(_path);
224        return Timestamp::fromFileTimeNP(fad.ftCreationTime.dwLowDateTime, fad.ftCreationTime.dwHighDateTime);
225}
226
227
228Timestamp FileImpl::getLastModifiedImpl() const
229{
230        poco_assert (!_path.empty());
231
232        WIN32_FILE_ATTRIBUTE_DATA fad;
233        if (GetFileAttributesEx(_path.c_str(), GetFileExInfoStandard, &fad) == 0) 
234                handleLastErrorImpl(_path);
235        return Timestamp::fromFileTimeNP(fad.ftLastWriteTime.dwLowDateTime, fad.ftLastWriteTime.dwHighDateTime);
236}
237
238
239void FileImpl::setLastModifiedImpl(const Timestamp& ts)
240{
241        poco_assert (!_path.empty());
242
243        UInt32 low;
244        UInt32 high;
245        ts.toFileTimeNP(low, high);
246        FILETIME ft;
247        ft.dwLowDateTime  = low;
248        ft.dwHighDateTime = high;
249        FileHandle fh(_path, FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
250        if (SetFileTime(fh.get(), 0, &ft, &ft) == 0)
251                handleLastErrorImpl(_path);
252}
253
254
255FileImpl::FileSizeImpl FileImpl::getSizeImpl() const
256{
257        poco_assert (!_path.empty());
258
259        WIN32_FILE_ATTRIBUTE_DATA fad;
260        if (GetFileAttributesEx(_path.c_str(), GetFileExInfoStandard, &fad) == 0) 
261                handleLastErrorImpl(_path);
262        LARGE_INTEGER li;
263        li.LowPart  = fad.nFileSizeLow;
264        li.HighPart = fad.nFileSizeHigh;
265        return li.QuadPart;
266}
267
268
269void FileImpl::setSizeImpl(FileSizeImpl size)
270{
271        poco_assert (!_path.empty());
272
273        FileHandle fh(_path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
274        LARGE_INTEGER li;
275        li.QuadPart = size;
276        if (SetFilePointer(fh.get(), li.LowPart, &li.HighPart, FILE_BEGIN) == -1)
277                handleLastErrorImpl(_path);
278        if (SetEndOfFile(fh.get()) == 0) 
279                handleLastErrorImpl(_path);
280}
281
282
283void FileImpl::setWriteableImpl(bool flag)
284{
285        poco_assert (!_path.empty());
286
287        DWORD attr = GetFileAttributes(_path.c_str());
288        if (attr == -1)
289                handleLastErrorImpl(_path);
290        if (flag)
291                attr &= ~FILE_ATTRIBUTE_READONLY;
292        else
293                attr |= FILE_ATTRIBUTE_READONLY;
294        if (SetFileAttributes(_path.c_str(), attr) == 0)
295                handleLastErrorImpl(_path);
296}
297
298
299void FileImpl::setExecutableImpl(bool flag)
300{
301        // not supported
302}
303
304
305void FileImpl::copyToImpl(const std::string& path) const
306{
307        poco_assert (!_path.empty());
308
309        if (CopyFileA(_path.c_str(), path.c_str(), FALSE) != 0) 
310        {
311                FileImpl copy(path);
312                copy.setWriteableImpl(true);
313        }
314        else handleLastErrorImpl(_path);
315}
316
317
318void FileImpl::renameToImpl(const std::string& path)
319{
320        poco_assert (!_path.empty());
321
322        if (MoveFileA(_path.c_str(), path.c_str()) == 0) 
323                handleLastErrorImpl(_path);
324}
325
326
327void FileImpl::removeImpl()
328{
329        poco_assert (!_path.empty());
330
331        if (isDirectoryImpl())
332        {
333                if (RemoveDirectoryA(_path.c_str()) == 0) 
334                        handleLastErrorImpl(_path);
335        }
336        else
337        {
338                if (DeleteFileA(_path.c_str()) == 0)
339                        handleLastErrorImpl(_path);
340        }
341}
342
343
344bool FileImpl::createFileImpl()
345{
346        poco_assert (!_path.empty());
347
348        HANDLE hFile = CreateFileA(_path.c_str(), GENERIC_WRITE, 0, 0, CREATE_NEW, 0, 0);
349        if (hFile != INVALID_HANDLE_VALUE)
350        {
351                CloseHandle(hFile);
352                return true;
353        }
354        else if (GetLastError() == ERROR_FILE_EXISTS)
355                return false;
356        else
357                handleLastErrorImpl(_path);
358        return false;
359}
360
361
362bool FileImpl::createDirectoryImpl()
363{
364        poco_assert (!_path.empty());
365       
366        if (existsImpl() && isDirectoryImpl())
367                return false;
368        if (CreateDirectoryA(_path.c_str(), 0) == 0)
369                handleLastErrorImpl(_path);
370        return true;
371}
372
373
374void FileImpl::handleLastErrorImpl(const std::string& path)
375{
376        switch (GetLastError())
377        {
378        case ERROR_FILE_NOT_FOUND:
379                throw FileNotFoundException(path);
380        case ERROR_PATH_NOT_FOUND:
381        case ERROR_BAD_NETPATH:
382        case ERROR_CANT_RESOLVE_FILENAME:
383        case ERROR_INVALID_DRIVE:
384                throw PathNotFoundException(path);
385        case ERROR_ACCESS_DENIED:
386                throw FileAccessDeniedException(path);
387        case ERROR_ALREADY_EXISTS:
388        case ERROR_FILE_EXISTS:
389                throw FileExistsException(path);
390        case ERROR_INVALID_NAME:
391        case ERROR_DIRECTORY:
392        case ERROR_FILENAME_EXCED_RANGE:
393        case ERROR_BAD_PATHNAME:
394                throw PathSyntaxException(path);
395        case ERROR_FILE_READ_ONLY:
396                throw FileReadOnlyException(path);
397        case ERROR_CANNOT_MAKE:
398                throw CreateFileException(path);
399        case ERROR_DIR_NOT_EMPTY:
400                throw FileException("directory not empty", path);
401        case ERROR_WRITE_FAULT:
402                throw WriteFileException(path);
403        case ERROR_READ_FAULT:
404                throw ReadFileException(path);
405        case ERROR_SHARING_VIOLATION:
406                throw FileException("sharing violation", path);
407        case ERROR_LOCK_VIOLATION:
408                throw FileException("lock violation", path);
409        case ERROR_HANDLE_EOF:
410                throw ReadFileException("EOF reached", path);
411        case ERROR_HANDLE_DISK_FULL:
412        case ERROR_DISK_FULL:
413                throw WriteFileException("disk is full", path);
414        case ERROR_NEGATIVE_SEEK:
415                throw FileException("negative seek", path);
416        default:
417                throw FileException(path);
418        }
419}
420
421
422} // namespace Poco
Note: See TracBrowser for help on using the repository browser.