Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
f3d2a8d4
Commit
f3d2a8d4
authored
Aug 20, 2003
by
Eric Pouech
Committed by
Alexandre Julliard
Aug 20, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Removed the DOSFS_ specific time related conversion routine, and make
use of the ntdll equivalents.
parent
61f84c18
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
12 additions
and
224 deletions
+12
-224
dos_fs.c
files/dos_fs.c
+12
-221
file.h
include/file.h
+0
-3
No files found.
files/dos_fs.c
View file @
f3d2a8d4
...
...
@@ -40,6 +40,8 @@
# include <unistd.h>
#endif
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winerror.h"
#include "wingdi.h"
...
...
@@ -2239,225 +2241,6 @@ BOOL WINAPI FindClose( HANDLE handle )
}
/***********************************************************************
* DOSFS_UnixTimeToFileTime
*
* Convert a Unix time to FILETIME format.
* The FILETIME structure is a 64-bit value representing the number of
* 100-nanosecond intervals since January 1, 1601, 0:00.
* 'remainder' is the nonnegative number of 100-ns intervals
* corresponding to the time fraction smaller than 1 second that
* couldn't be stored in the time_t value.
*/
void
DOSFS_UnixTimeToFileTime
(
time_t
unix_time
,
FILETIME
*
filetime
,
DWORD
remainder
)
{
/* NOTES:
CONSTANTS:
The time difference between 1 January 1601, 00:00:00 and
1 January 1970, 00:00:00 is 369 years, plus the leap years
from 1604 to 1968, excluding 1700, 1800, 1900.
This makes (1968 - 1600) / 4 - 3 = 89 leap days, and a total
of 134774 days.
Any day in that period had 24 * 60 * 60 = 86400 seconds.
The time difference is 134774 * 86400 * 10000000, which can be written
116444736000000000
27111902 * 2^32 + 3577643008
413 * 2^48 + 45534 * 2^32 + 54590 * 2^16 + 32768
If you find that these constants are buggy, please change them in all
instances in both conversion functions.
VERSIONS:
There are two versions, one of them uses long long variables and
is presumably faster but not ISO C. The other one uses standard C
data types and operations but relies on the assumption that negative
numbers are stored as 2's complement (-1 is 0xffff....). If this
assumption is violated, dates before 1970 will not convert correctly.
This should however work on any reasonable architecture where WINE
will run.
DETAILS:
Take care not to remove the casts. I have tested these functions
(in both versions) for a lot of numbers. I would be interested in
results on other compilers than GCC.
The operations have been designed to account for the possibility
of 64-bit time_t in future UNICES. Even the versions without
internal long long numbers will work if time_t only is 64 bit.
A 32-bit shift, which was necessary for that operation, turned out
not to work correctly in GCC, besides giving the warning. So I
used a double 16-bit shift instead. Numbers are in the ISO version
represented by three limbs, the most significant with 32 bit, the
other two with 16 bit each.
As the modulo-operator % is not well-defined for negative numbers,
negative divisors have been avoided in DOSFS_FileTimeToUnixTime.
There might be quicker ways to do this in C. Certainly so in
assembler.
Claus Fischer, fischer@iue.tuwien.ac.at
*/
#if SIZEOF_LONG_LONG >= 8
# define USE_LONG_LONG 1
#else
# define USE_LONG_LONG 0
#endif
#if USE_LONG_LONG
/* gcc supports long long type */
long
long
int
t
=
unix_time
;
t
*=
10000000
;
t
+=
116444736000000000LL
;
t
+=
remainder
;
filetime
->
dwLowDateTime
=
(
UINT
)
t
;
filetime
->
dwHighDateTime
=
(
UINT
)(
t
>>
32
);
#else
/* ISO version */
UINT
a0
;
/* 16 bit, low bits */
UINT
a1
;
/* 16 bit, medium bits */
UINT
a2
;
/* 32 bit, high bits */
/* Copy the unix time to a2/a1/a0 */
a0
=
unix_time
&
0xffff
;
a1
=
(
unix_time
>>
16
)
&
0xffff
;
/* This is obsolete if unix_time is only 32 bits, but it does not hurt.
Do not replace this by >> 32, it gives a compiler warning and it does
not work. */
a2
=
(
unix_time
>=
0
?
(
unix_time
>>
16
)
>>
16
:
~
((
~
unix_time
>>
16
)
>>
16
));
/* Multiply a by 10000000 (a = a2/a1/a0)
Split the factor into 10000 * 1000 which are both less than 0xffff. */
a0
*=
10000
;
a1
=
a1
*
10000
+
(
a0
>>
16
);
a2
=
a2
*
10000
+
(
a1
>>
16
);
a0
&=
0xffff
;
a1
&=
0xffff
;
a0
*=
1000
;
a1
=
a1
*
1000
+
(
a0
>>
16
);
a2
=
a2
*
1000
+
(
a1
>>
16
);
a0
&=
0xffff
;
a1
&=
0xffff
;
/* Add the time difference and the remainder */
a0
+=
32768
+
(
remainder
&
0xffff
);
a1
+=
54590
+
(
remainder
>>
16
)
+
(
a0
>>
16
);
a2
+=
27111902
+
(
a1
>>
16
);
a0
&=
0xffff
;
a1
&=
0xffff
;
/* Set filetime */
filetime
->
dwLowDateTime
=
(
a1
<<
16
)
+
a0
;
filetime
->
dwHighDateTime
=
a2
;
#endif
}
/***********************************************************************
* DOSFS_FileTimeToUnixTime
*
* Convert a FILETIME format to Unix time.
* If not NULL, 'remainder' contains the fractional part of the filetime,
* in the range of [0..9999999] (even if time_t is negative).
*/
time_t
DOSFS_FileTimeToUnixTime
(
const
FILETIME
*
filetime
,
DWORD
*
remainder
)
{
/* Read the comment in the function DOSFS_UnixTimeToFileTime. */
#if USE_LONG_LONG
long
long
int
t
=
filetime
->
dwHighDateTime
;
t
<<=
32
;
t
+=
(
UINT
)
filetime
->
dwLowDateTime
;
t
-=
116444736000000000LL
;
if
(
t
<
0
)
{
if
(
remainder
)
*
remainder
=
9999999
-
(
-
t
-
1
)
%
10000000
;
return
-
1
-
((
-
t
-
1
)
/
10000000
);
}
else
{
if
(
remainder
)
*
remainder
=
t
%
10000000
;
return
t
/
10000000
;
}
#else
/* ISO version */
UINT
a0
;
/* 16 bit, low bits */
UINT
a1
;
/* 16 bit, medium bits */
UINT
a2
;
/* 32 bit, high bits */
UINT
r
;
/* remainder of division */
unsigned
int
carry
;
/* carry bit for subtraction */
int
negative
;
/* whether a represents a negative value */
/* Copy the time values to a2/a1/a0 */
a2
=
(
UINT
)
filetime
->
dwHighDateTime
;
a1
=
((
UINT
)
filetime
->
dwLowDateTime
)
>>
16
;
a0
=
((
UINT
)
filetime
->
dwLowDateTime
)
&
0xffff
;
/* Subtract the time difference */
if
(
a0
>=
32768
)
a0
-=
32768
,
carry
=
0
;
else
a0
+=
(
1
<<
16
)
-
32768
,
carry
=
1
;
if
(
a1
>=
54590
+
carry
)
a1
-=
54590
+
carry
,
carry
=
0
;
else
a1
+=
(
1
<<
16
)
-
54590
-
carry
,
carry
=
1
;
a2
-=
27111902
+
carry
;
/* If a is negative, replace a by (-1-a) */
negative
=
(
a2
>=
((
UINT
)
1
)
<<
31
);
if
(
negative
)
{
/* Set a to -a - 1 (a is a2/a1/a0) */
a0
=
0xffff
-
a0
;
a1
=
0xffff
-
a1
;
a2
=
~
a2
;
}
/* Divide a by 10000000 (a = a2/a1/a0), put the rest into r.
Split the divisor into 10000 * 1000 which are both less than 0xffff. */
a1
+=
(
a2
%
10000
)
<<
16
;
a2
/=
10000
;
a0
+=
(
a1
%
10000
)
<<
16
;
a1
/=
10000
;
r
=
a0
%
10000
;
a0
/=
10000
;
a1
+=
(
a2
%
1000
)
<<
16
;
a2
/=
1000
;
a0
+=
(
a1
%
1000
)
<<
16
;
a1
/=
1000
;
r
+=
(
a0
%
1000
)
*
10000
;
a0
/=
1000
;
/* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
if
(
negative
)
{
/* Set a to -a - 1 (a is a2/a1/a0) */
a0
=
0xffff
-
a0
;
a1
=
0xffff
-
a1
;
a2
=
~
a2
;
r
=
9999999
-
r
;
}
if
(
remainder
)
*
remainder
=
r
;
/* Do not replace this by << 32, it gives a compiler warning and it does
not work. */
return
((((
time_t
)
a2
)
<<
16
)
<<
16
)
+
(
a1
<<
16
)
+
a0
;
#endif
}
/***********************************************************************
* MulDiv (KERNEL32.@)
* RETURNS
* Result of multiplication and division
...
...
@@ -2545,8 +2328,16 @@ BOOL WINAPI DosDateTimeToFileTime( WORD fatdate, WORD fattime, LPFILETIME ft)
BOOL
WINAPI
FileTimeToDosDateTime
(
const
FILETIME
*
ft
,
LPWORD
fatdate
,
LPWORD
fattime
)
{
time_t
unixtime
=
DOSFS_FileTimeToUnixTime
(
ft
,
NULL
);
struct
tm
*
tm
=
gmtime
(
&
unixtime
);
LARGE_INTEGER
li
;
ULONG
t
;
time_t
unixtime
;
struct
tm
*
tm
;
li
.
s
.
LowPart
=
ft
->
dwLowDateTime
;
li
.
s
.
HighPart
=
ft
->
dwHighDateTime
;
RtlTimeToSecondsSince1970
(
&
li
,
&
t
);
unixtime
=
t
;
tm
=
gmtime
(
&
unixtime
);
if
(
fattime
)
*
fattime
=
(
tm
->
tm_hour
<<
11
)
+
(
tm
->
tm_min
<<
5
)
+
(
tm
->
tm_sec
/
2
);
if
(
fatdate
)
...
...
include/file.h
View file @
f3d2a8d4
...
...
@@ -94,9 +94,6 @@ extern DWORD DIR_SearchPath( LPCWSTR path, LPCWSTR name, LPCWSTR ext,
DOS_FULL_NAME
*
full_name
,
BOOL
win32
);
/* files/dos_fs.c */
extern
void
DOSFS_UnixTimeToFileTime
(
time_t
unixtime
,
LPFILETIME
ft
,
DWORD
remainder
);
extern
time_t
DOSFS_FileTimeToUnixTime
(
const
FILETIME
*
ft
,
DWORD
*
remainder
);
extern
BOOL
DOSFS_ToDosFCBFormat
(
LPCWSTR
name
,
LPWSTR
buffer
);
extern
const
DOS_DEVICE
*
DOSFS_GetDevice
(
LPCWSTR
name
);
extern
const
DOS_DEVICE
*
DOSFS_GetDeviceByHandle
(
HANDLE
hFile
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment