www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - calling C functions findfirst etc

reply "Regan Heath" <regan netwin.co.nz> writes:
------------G5FaL5SajqwBDVSW69Khb2
Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15
Content-Transfer-Encoding: 8bit

I am trying to call the C function findfirst. It fills a struct with file  
information.

I have converted the parts of the C header io.h that I believe are  
required.
It links, it runs, it gets garbage.

I have attached my code (b.d) and a test done in C (test.c).

Running both you can see the address and size of each struct member  
involved.

Anyone know what I am doing wrong?

Regan
------------G5FaL5SajqwBDVSW69Khb2
Content-Disposition: attachment; filename=b.d
Content-Type: application/octet-stream; name=b.d
Content-Transfer-Encoding: 8bit

import std.string;

version(Windows) {	
	extern(C) {
		typedef int  time_t;
		typedef uint _fsize_t;

		align(8) struct finddata_t {
		    uint 	attrib;
		    time_t      time_create;
		    time_t      time_access;
		    time_t      time_write;
		    _fsize_t    size;
		    char        name[260];
		}

		align(8) struct finddatai64_t {
		    uint	attrib;
		    time_t      time_create;
		    time_t      time_access;
		    time_t      time_write;
		    long	size;
		    char        name[260];
		}

		int findfirst(char *filespec, finddata_t *fileinfo);
		int findnext(int handle, finddata_t *fileinfo);
		int _findclose(int handle);

		long findfirsti64(char *filespec, finddatai64_t *fileinfo);
		long findnexti64(int handle, finddatai64_t *fileinfo);

		uint A_NORMAL		= 0x00;
		uint A_RDONLY		= 0x01;
		uint A_HIDDEN		= 0x02;
		uint A_SYSTEM		= 0x04;
		uint A_SUBDIR		= 0x10;
		uint A_ARCH		= 0x20;
	}
}

int main(char[][] args)
{
	finddata_t data;
	int handle;
	
	handle = findfirst("*",&data);
	printf("%d\n",handle);
	
	printf("\n");

	printf("%08x\n",&data);
	printf("%08x %d\n",&data.attrib,data.attrib.sizeof);
	printf("%08x %d\n",&data.time_create,data.time_create.sizeof);
	printf("%08x %d\n",&data.time_access,data.time_access.sizeof);	
	printf("%08x %d\n",&data.time_write,data.time_write.sizeof);
	printf("%08x %d\n",&data.size,data.size.sizeof);
	printf("%08x %d\n",&data.name,data.name.sizeof);

	printf("\n");
	
	printf("%d\n",data.attrib);
	printf("%d\n",data.time_create);
	printf("%d\n",data.time_access);
	printf("%d\n",data.time_write);
	printf("%d\n",data.size);
	printf("(%s)\n",data.name);
	
	return 0;
}
------------G5FaL5SajqwBDVSW69Khb2
Content-Disposition: attachment; filename=test.c
Content-Type: application/octet-stream; name=test.c
Content-Transfer-Encoding: 8bit

#include <stdlib.h>
#include <stdio.h>
#include <io.h>

int main()
{
	struct _finddata_t data;
	int handle;

	handle = _findfirst("*",&data);
	if (handle == -1) exit(1);

	printf("%d\n",handle);

	printf("\n");

	printf("%08x\n",&data);
	printf("%08x %d\n",&data.attrib,sizeof(data.attrib));
	printf("%08x %d\n",&data.time_create,sizeof(data.time_create));
	printf("%08x %d\n",&data.time_access,sizeof(data.time_access));	
	printf("%08x %d\n",&data.time_write,sizeof(data.time_write));
	printf("%08x %d\n",&data.size,sizeof(data.size));
	printf("%08x %d\n",&data.name,sizeof(data.name));

	printf("\n");
	
	printf("%d\n",data.attrib);
	printf("%d\n",data.time_create);
	printf("%d\n",data.time_access);
	printf("%d\n",data.time_write);
	printf("%d\n",data.size);
	printf("(%s)\n",data.name);

	return 0;
}
------------G5FaL5SajqwBDVSW69Khb2--
Apr 11 2005
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message 
news:opso2eamu423k2f5 nrage.netwin.co.nz...
 Anyone know what I am doing wrong?

I'm not sure but it may be the align(8) directives. Align takes the number of bytes to align to, not bits. As of now it's aligning the members on 8-byte boundaries! So you'd want to write "align(1)" instead.
Apr 11 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 11 Apr 2005 16:53:33 -0400, Jarrett Billingsley  
<kb3ctd2 yahoo.com> wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opso2eamu423k2f5 nrage.netwin.co.nz...
 Anyone know what I am doing wrong?

I'm not sure but it may be the align(8) directives. Align takes the number of bytes to align to, not bits. As of now it's aligning the members on 8-byte boundaries! So you'd want to write "align(1)" instead.

Tried it, no luck. After posting I looked at the io.h in the dmc.zip (the linker zip for D) from digital mars, it does not contain #pragma pack(push,8) like the MSVC one did, I have tried without align, and with align 1 or 8 it makes no difference. Regan
Apr 11 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message 
news:opso25soy023k2f5 nrage.netwin.co.nz...
 Tried it, no luck. After posting I looked at the io.h in the dmc.zip (the 
 linker zip for D) from digital mars, it does not contain #pragma 
 pack(push,8) like the MSVC one did, I have tried without align, and with 
 align 1 or 8 it makes no difference.

Hm. Well I tried running your program, and this is what I got:
 Executing: C:\ConTEXT\ConExec.exe "C:\dmd\proj\dtest\run.bat"

4282528 0012fe20 0012fe20 4 0012fe24 4 0012fe28 4 0012fe2c 4 0012fe30 4 0012fe34 260 0 0 0 0 0 (Error: Access Violation The access violation is because you're using %s as the format modifier. Using %.*s, or using data.name.ptr instead makes it work. But then it's just filled with character 255 (default character value). I don't know what to tell you.
Apr 11 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 11 Apr 2005 17:27:17 -0400, Jarrett Billingsley  
<kb3ctd2 yahoo.com> wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opso25soy023k2f5 nrage.netwin.co.nz...
 Tried it, no luck. After posting I looked at the io.h in the dmc.zip  
 (the
 linker zip for D) from digital mars, it does not contain #pragma
 pack(push,8) like the MSVC one did, I have tried without align, and with
 align 1 or 8 it makes no difference.

Hm. Well I tried running your program, and this is what I got:
 Executing: C:\ConTEXT\ConExec.exe "C:\dmd\proj\dtest\run.bat"

4282528 0012fe20 0012fe20 4 0012fe24 4 0012fe28 4 0012fe2c 4 0012fe30 4 0012fe34 260 0 0 0 0 0 (Error: Access Violation

Yep. That's what I get also.
 The access violation is because you're using %s as the format modifier.

Which should be correct for a C string. Right?
 Using %.*s, or using data.name.ptr instead makes it work.  But then it's
 just filled with character 255 (default character value).

I tried that also. It appears to be treating the char as a D char, not a C char, should I be using byte instead perhaps? Basically it needs to be a fixed size block of memory that is not a D array.
 I don't know what to tell you.

Well, at least that means I haven't missed something obvious, which is good and bad all at the same time. Hopefully Walter (or someone else) knows what's going on. Regan
Apr 11 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message 
news:opso27fqem23k2f5 nrage.netwin.co.nz...
 I tried that also. It appears to be treating the char as a D char, not a C 
 char, should I be using byte instead perhaps? Basically it needs to be a 
 fixed size block of memory that is not a D array.

char[260] is a D char array. It's static, but it still has the same layout as a dynamic char array -- length, then pointer to the data. Thus, you still must use %.*s, or use %s with the .ptr of the array.
Apr 11 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Mon, 11 Apr 2005 20:52:02 -0400, Jarrett Billingsley  
<kb3ctd2 yahoo.com> wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opso27fqem23k2f5 nrage.netwin.co.nz...
 I tried that also. It appears to be treating the char as a D char, not  
 a C
 char, should I be using byte instead perhaps? Basically it needs to be a
 fixed size block of memory that is not a D array.

char[260] is a D char array. It's static, but it still has the same layout as a dynamic char array -- length, then pointer to the data. Thus, you still must use %.*s, or use %s with the .ptr of the array.

char[] a; char[100] b; char c[100]; I *thought* 'c' was different to 'b'. I guess not. How do you represent a C array of chars/bytes/ints/longs etc? The conversion guide says to use "byte" in place of C's "signed char", but the same problem occurs as "byte c[100]" is a D style array, yes? So that leaves "byte* c". However, this will effect the size of the struct and the C function will write "past the end" of the struct passed to it, right? I am at a loss... Regan
Apr 11 2005
parent reply brad domain.invalid writes:
Regan Heath wrote:
 On Mon, 11 Apr 2005 20:52:02 -0400, Jarrett Billingsley  
 <kb3ctd2 yahoo.com> wrote:
 
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opso27fqem23k2f5 nrage.netwin.co.nz...

 I tried that also. It appears to be treating the char as a D char, 
 not  a C
 char, should I be using byte instead perhaps? Basically it needs to be a
 fixed size block of memory that is not a D array.

char[260] is a D char array. It's static, but it still has the same layout as a dynamic char array -- length, then pointer to the data. Thus, you still must use %.*s, or use %s with the .ptr of the array.

char[] a; char[100] b; char c[100]; I *thought* 'c' was different to 'b'. I guess not. How do you represent a C array of chars/bytes/ints/longs etc? The conversion guide says to use "byte" in place of C's "signed char", but the same problem occurs as "byte c[100]" is a D style array, yes? So that leaves "byte* c". However, this will effect the size of the struct and the C function will write "past the end" of the struct passed to it, right? I am at a loss... Regan

I think that you are correct - otherwise things are very broken... struct A { char a[12]; } int main(char [][]args) { printf("sizeof a %i\n", A.sizeof); } Gives the expected output of 12, no hidden length marker. Brad
Apr 11 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 12 Apr 2005 14:29:56 +1200, <brad domain.invalid> wrote:
 Regan Heath wrote:
 On Mon, 11 Apr 2005 20:52:02 -0400, Jarrett Billingsley   
 <kb3ctd2 yahoo.com> wrote:

 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opso27fqem23k2f5 nrage.netwin.co.nz...

 I tried that also. It appears to be treating the char as a D char,  
 not  a C
 char, should I be using byte instead perhaps? Basically it needs to  
 be a
 fixed size block of memory that is not a D array.

char[260] is a D char array. It's static, but it still has the same layout as a dynamic char array -- length, then pointer to the data. Thus, you still must use %.*s, or use %s with the .ptr of the array.

char[100] b; char c[100]; I *thought* 'c' was different to 'b'. I guess not. How do you represent a C array of chars/bytes/ints/longs etc? The conversion guide says to use "byte" in place of C's "signed char", but the same problem occurs as "byte c[100]" is a D style array, yes? So that leaves "byte* c". However, this will effect the size of the struct and the C function will write "past the end" of the struct passed to it, right? I am at a loss... Regan

I think that you are correct - otherwise things are very broken... struct A { char a[12]; } int main(char [][]args) { printf("sizeof a %i\n", A.sizeof); } Gives the expected output of 12, no hidden length marker.

I suspect they're identical. I suspect they're both C type arrays. I suspect the compiler replaces things like "b.length" with the actual length at compile time. I dont think this is related to the original problem. struct A { char[] a; } struct B { char[100] b; } struct C { char c[100]; } int main(char[][] args) { char[] a; char[100] b; char c[100]; A sa; B sb; C sc; printf("%d %08x %08x\n",a.sizeof,&a,a.ptr); printf("%d %08x %08x\n",b.sizeof,&b,b.ptr); printf("%d %08x %08x\n",c.sizeof,&c,c.ptr); printf("%d\n",sa.sizeof); printf("%d\n",sb.sizeof); printf("%d\n",sc.sizeof); } Output: 8 0012fd88 00000000 100 0012fd90 0012fd90 100 0012fdf4 0012fdf4 8 100 100 Regan
Apr 11 2005
prev sibling next sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Regan Heath" <regan netwin.co.nz> wrote in message 
news:opso2eamu423k2f5 nrage.netwin.co.nz...
I am trying to call the C function findfirst. It fills a struct with file
 information.

 I have converted the parts of the C header io.h that I believe are
 required.
 It links, it runs, it gets garbage.

 I have attached my code (b.d) and a test done in C (test.c).

 Running both you can see the address and size of each struct member
 involved.

 Anyone know what I am doing wrong?

 Regan

Googling for "digitalmars findfirst" turns up some links that indicate the DMC++ version of findfirst isn't like the others. Maybe try "dos_findfirst"? I'm not really sure. Check out dm/include/dos.h for dos_findfirst.
Apr 11 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
------------ylNqFhlhHuWtqTMCyJbECz
Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15
Content-Transfer-Encoding: 8bit

On Mon, 11 Apr 2005 23:08:15 -0400, Ben Hinkle <ben.hinkle gmail.com>  
wrote:
 "Regan Heath" <regan netwin.co.nz> wrote in message
 news:opso2eamu423k2f5 nrage.netwin.co.nz...
 I am trying to call the C function findfirst. It fills a struct with  
 file
 information.

 I have converted the parts of the C header io.h that I believe are
 required.
 It links, it runs, it gets garbage.

 I have attached my code (b.d) and a test done in C (test.c).

 Running both you can see the address and size of each struct member
 involved.

 Anyone know what I am doing wrong?

 Regan

Googling for "digitalmars findfirst" turns up some links that indicate the DMC++ version of findfirst isn't like the others. Maybe try "dos_findfirst"? I'm not really sure. Check out dm/include/dos.h for dos_findfirst.

Found it. Tried it. I cannot get it to link. I think I am missing the required lib. Grepping the lib dir for findfirst finds it in snn.lib, but dos_findfirst is not found in any lib. Attached is my current test case. Regan ------------ylNqFhlhHuWtqTMCyJbECz Content-Disposition: attachment; filename=b.d Content-Type: application/octet-stream; name=b.d Content-Transfer-Encoding: 8bit import std.string; version(Windows) { extern(C) { typedef int time_t; typedef uint _fsize_t; align(1) struct finddata_t { uint attrib; time_t time_create; time_t time_access; time_t time_write; _fsize_t size; byte* name; } align(1) struct finddatai64_t { uint attrib; time_t time_create; time_t time_access; time_t time_write; long size; byte* name; } int findfirst(char *filespec, finddata_t *fileinfo); int findnext(int handle, finddata_t *fileinfo); int _findclose(int handle); long findfirsti64(char *filespec, finddatai64_t *fileinfo); long findnexti64(int handle, finddatai64_t *fileinfo); uint A_NORMAL = 0x00; uint A_RDONLY = 0x01; uint A_HIDDEN = 0x02; uint A_SYSTEM = 0x04; uint A_SUBDIR = 0x10; uint A_ARCH = 0x20; } } version(Windows) { extern(C) { struct find_t { char reserved[21]; char attrib; ushort wr_time,wr_date; uint size; char name[260]; } uint dos_findfirst(char *, uint, find_t *); uint dos_findnext(find_t *); uint FA_NORMAL = 0x00; uint FA_RDONLY = 0x01; uint FA_HIDDEN = 0x02; uint FA_SYSTEM = 0x04; uint FA_LABEL = 0x08; uint FA_DIREC = 0x10; uint FA_ARCH = 0x20; uint _A_NORMAL = 0x00; uint _A_RDONLY = 0x01; uint _A_HIDDEN = 0x02; uint _A_SYSTEM = 0x04; uint _A_VOLID = 0x08; uint _A_SUBDIR = 0x10; uint _A_ARCH = 0x20; } } int main(char[][] args) { { finddata_t data; int handle; handle = findfirst(toStringz("*.*"),&data); printf("%d\n",handle); printf("\n"); printf("%08x\n",&data); printf("%08x %d\n",&data.attrib,data.attrib.sizeof); printf("%08x %d\n",&data.time_create,data.time_create.sizeof); printf("%08x %d\n",&data.time_access,data.time_access.sizeof); printf("%08x %d\n",&data.time_write,data.time_write.sizeof); printf("%08x %d\n",&data.size,data.size.sizeof); printf("%08x %d\n",&data.name,data.name.sizeof); printf("\n"); printf("%d\n",data.attrib); printf("%d\n",data.time_create); printf("%d\n",data.time_access); printf("%d\n",data.time_write); printf("%d\n",data.size); printf("(%s)\n",data.name); } { find_t data; uint handle; handle = dos_findfirst(toStringz("*.*"),_A_NORMAL,&data); printf("%d\n",handle); printf("\n"); printf("%08x\n",&data); printf("%08x %d\n",&data.attrib,data.attrib.sizeof); printf("%08x %d\n",&data.wr_time,data.wr_time.sizeof); printf("%08x %d\n",&data.wr_date,data.wr_date.sizeof); printf("%08x %d\n",&data.size,data.size.sizeof); printf("%08x %d\n",&data.name,data.name.sizeof); printf("\n"); printf("%d\n",data.attrib); printf("%d\n",data.wr_time); printf("%d\n",data.wr_date); printf("%d\n",data.size); printf("(%s)\n",data.name); } return 0; } ------------ylNqFhlhHuWtqTMCyJbECz--
Apr 11 2005
prev sibling parent reply David L. Davis <SpottedTiger yahoo.com> writes:
In article <opso2eamu423k2f5 nrage.netwin.co.nz>, Regan Heath says...
------------G5FaL5SajqwBDVSW69Khb2
Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15
Content-Transfer-Encoding: 8bit

I am trying to call the C function findfirst. It fills a struct with file  
information.

I have converted the parts of the C header io.h that I believe are  
required.
It links, it runs, it gets garbage.

I have attached my code (b.d) and a test done in C (test.c).

Running both you can see the address and size of each struct member  
involved.

Anyone know what I am doing wrong?

Regan

Regan maybe this code would be helpful, here's a ported example I've done using Windows' Win32 API FindFirstFile() function. # /+ # MSDN Online Library - FindFirstFile Example # http://msdn.microsoft.com/library/default.asp? # url=/library/en-us/fileio/base/findfirstfile.asp # # #define _WIN32_WINNT 0x0400 # # #include <windows.h> # #include <stdio.h> # # int main(int argc, char *argv[]) # { # WIN32_FIND_DATA FindFileData; # HANDLE hFind; # # printf ("Target file is %s.\n", argv[1]); # hFind = FindFirstFile(argv[1], &FindFileData); # if (hFind == INVALID_HANDLE_VALUE) # { # printf ("Invalid File Handle. GetLastError reports %d\n", # GetLastError ()); # return (0); # } # else # { # printf ("The first file found is %s\n", FindFileData.cFileName); # FindClose(hFind); # return (1); # } # } # +/ # # // Win32 API example of FindFirstFile() # private import std.c.windows.windows; # private import std.string; # private import std.stdio; # # int main( char[][] args ) # { # WIN32_FIND_DATA FindFileData; # HANDLE hFind; # # if ( args.length <= 1 ) # { # writefln( "Parameter missing, try the following... # FindFirstFile \"C:\\Test.txt\"" ); # return 1; # } # # hFind = FindFirstFileA( args[ 1 ], &FindFileData ); # # if ( hFind == INVALID_HANDLE_VALUE ) # { # writefln( "File not found or Invalid File Handle. # GetLastError reports %d", GetLastError() ); # return 0; # } # else # { # writefln( "The first file found is %s", # toString( FindFileData.cFileName ) ); # # //writefln( "%08x %d", data.dwFileAttributes, # data.dwFileAttributes.sizeof ); # FileTimeToSystemTime( &data.ftCreationTime, lpSystemTime); # writefln( "Created=%02d/%02d/%04d %d", # systime.wDay, systime.wMonth, systime.wYear, # data.ftCreationTime.sizeof ); # # FileTimeToSystemTime( &data.ftLastAccessTime, lpSystemTime); # writefln( "Last Access=%02d/%02d/%04d %d", # systime.wDay, systime.wMonth, systime.wYear, # data.ftLastAccessTime.sizeof ); # # FileTimeToSystemTime( & data.ftLastWriteTime, lpSystemTime); # # writefln( "Last Written=%02d/%02d/%04d %d", # systime.wDay, systime.wMonth, systime.wYear, # data.ftLastWriteTime.sizeof ); # # writefln( "%08x %d", data.nFileSizeLow, # data.nFileSizeLow.sizeof ); # writefln( "%s %d", toString( data.cFileName ), # data.cFileName.sizeof ); # # FindClose( hFind ); # return 1; # } # # return 0; # } Output in the WinXP console: ---------------------------- C:\dmd>dmd findfirstfile.d C:\dmd\bin\..\..\dm\bin\link.exe findfirstfile,,,user32+kernel32/noi; C:\dmd>findfirstfile "C:\test.txt" The first file found is Test.txt C:\dmd>findfirstfile "C:\*.*" The first file found is 1DPR00714.MTF C:\dmd>findfirstfile "C:\*.txt" The first file found is Support Issue.txt C:\dmd>findfirstfile "C:\*.lic" File not found or Invalid File Handle. GetLastError reports 2 C:\dmd> David L. ------------------------------------------------------------------- "Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
Apr 12 2005
parent reply David L. Davis <SpottedTiger yahoo.com> writes:
Opps!! 

Please add these inside main()

SYSTEMTIME      systime;
SYSTEMTIME*     lpSystemTime = &systime;

I had commented the main code with "#"s and then I decided to add more code and
thought I had added all my changes to it, but it looks like I missed these.
Sorry about that.

David L.

-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
Apr 12 2005
parent reply David L. Davis <SpottedTiger yahoo.com> writes:
Ok...it looks like the lazy way of "cut and paste" is not going to save me any
time or work. :( I've just recommented the current working version...sorry
everybody for number of posts its take, just to get a simple example posted
correctly. 

I think I'll go hide under a rock now, until tomorrow.

# /+
#  MSDN Online Library - FindFirstFile Example found at:
#  http://msdn.microsoft.com/library/default.asp
#         ?url=/library/en-us/fileio/base/findfirstfile.asp
#
#  #define _WIN32_WINNT 0x0400
#
#  #include <windows.h>
#  #include <stdio.h>
#
#  int main(int argc, char *argv[])
#  {
#    WIN32_FIND_DATA FindFileData;
#    HANDLE hFind;
#
#    printf ("Target file is %s.\n", argv[1]);
#    hFind = FindFirstFile(argv[1], &FindFileData);
#    if (hFind == INVALID_HANDLE_VALUE) 
#    {
#      printf ("Invalid File Handle. GetLastError reports %d\n", 
#               GetLastError ());
#      return (0);
#    } 
#    else 
#    {
#      printf ("The first file found is %s\n", FindFileData.cFileName);
#      FindClose(hFind);
#      return (1);
#    }
#  }
# +/
#
# // Win32 API example of FindFirstFile()
# private import std.c.windows.windows;
# private import std.string;
# private import std.stdio;
# 
# int main( char[][] args )
# {
#     WIN32_FIND_DATA data;
#     HANDLE          hFind;
#     SYSTEMTIME      systime;
#     SYSTEMTIME*     lpSystemTime = &systime;
#
#     if ( args.length <= 1 )
#     {
#         writefln( "Parameter missing, try the following...
#                    FindFirstFile \"C:\\Test.txt\"" );
#         return 1;
#     }
#         
#     hFind = FindFirstFileA( args[ 1 ], &data );
#    
#     if ( hFind == INVALID_HANDLE_VALUE ) 
#     {
#         writefln( "File not found or Invalid File Handle. 
#                    GetLastError reports %d", GetLastError() );
#         return 0;
#     } 
#     else 
#     {
#         writefln( "The first file found is %s", toString( data.cFileName ) );
#         //writefln( "%08x %d", data.dwFileAttributes, 
#                      data.dwFileAttributes.sizeof );
#
#         FileTimeToSystemTime( &data.ftCreationTime, lpSystemTime);
#         writefln( "Created=%02d/%02d/%04d %d", 
#                    systime.wDay, systime.wMonth, systime.wYear, 
#                    data.ftCreationTime.sizeof );
#	
#         FileTimeToSystemTime( &data.ftLastAccessTime, lpSystemTime);
#         writefln( "Last Access=%02d/%02d/%04d %d", 
#                    systime.wDay, systime.wMonth, systime.wYear, 
#                    data.ftLastAccessTime.sizeof );
#		
#         FileTimeToSystemTime( & data.ftLastWriteTime, lpSystemTime);	
#	
#         writefln( "Last Written=%02d/%02d/%04d %d", 
#                    systime.wDay, systime.wMonth, systime.wYear, 
#                    data.ftLastWriteTime.sizeof );
#	
#         writefln( "%08x %d", data.nFileSizeLow,
#                   data.nFileSizeLow.sizeof );
#         writefln( "%s %d", toString( data.cFileName ), 
#                            data.cFileName.sizeof );
#
#         FindClose( hFind );
#         return 1;
#     }
#    
#     return 0;   
# }

Output in the WinXP Console:
----------------------------
C:\dmd>dmd findfirstfile.d
C:\dmd\bin\..\..\dm\bin\link.exe findfirstfile,,,user32+kernel32/noi;

C:\dmd>findfirstfile "C:\test.txt"
The first file found is Test.txt
Created=12/04/2005 8
Last Access=12/04/2005 8
Last Written=12/04/2005 8
0000000e 4
Test.txt 260

C:\dmd>findfirstfile "C:\*.*"
The first file found is 1DPR00714.MTF
Created=03/02/2005 8
Last Access=01/04/2005 8
Last Written=03/02/2005 8
000048d2 4
1DPR00714.MTF 260

C:\dmd>findfirstfile "C:\*.txt"
The first file found is Support Issue.txt
Created=01/12/2004 8
Last Access=18/01/2005 8
Last Written=01/12/2004 8
0001147d 4
BeginNew Support Issue.txt 260

C:\dmd>findfirstfile "C:\*.lic"
File not found or Invalid File Handle. GetLastError reports 2

C:\dmd>

David L.

-------------------------------------------------------------------
"Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"
Apr 12 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
Thanks David. This works, though I am still interested in why the other  
one fails.

Regan

On Tue, 12 Apr 2005 18:39:23 +0000 (UTC), David L. Davis  
<SpottedTiger yahoo.com> wrote:
 Ok...it looks like the lazy way of "cut and paste" is not going to save  
 me any
 time or work. :( I've just recommented the current working  
 version...sorry
 everybody for number of posts its take, just to get a simple example  
 posted
 correctly.

 I think I'll go hide under a rock now, until tomorrow.

 # /+
 #  MSDN Online Library - FindFirstFile Example found at:
 #  http://msdn.microsoft.com/library/default.asp
 #         ?url=/library/en-us/fileio/base/findfirstfile.asp
 #
 #  #define _WIN32_WINNT 0x0400
 #
 #  #include <windows.h>
 #  #include <stdio.h>
 #
 #  int main(int argc, char *argv[])
 #  {
 #    WIN32_FIND_DATA FindFileData;
 #    HANDLE hFind;
 #
 #    printf ("Target file is %s.\n", argv[1]);
 #    hFind = FindFirstFile(argv[1], &FindFileData);
 #    if (hFind == INVALID_HANDLE_VALUE)
 #    {
 #      printf ("Invalid File Handle. GetLastError reports %d\n",
 #               GetLastError ());
 #      return (0);
 #    }
 #    else
 #    {
 #      printf ("The first file found is %s\n", FindFileData.cFileName);
 #      FindClose(hFind);
 #      return (1);
 #    }
 #  }
 # +/
 #
 # // Win32 API example of FindFirstFile()
 # private import std.c.windows.windows;
 # private import std.string;
 # private import std.stdio;
 #
 # int main( char[][] args )
 # {
 #     WIN32_FIND_DATA data;
 #     HANDLE          hFind;
 #     SYSTEMTIME      systime;
 #     SYSTEMTIME*     lpSystemTime = &systime;
 #
 #     if ( args.length <= 1 )
 #     {
 #         writefln( "Parameter missing, try the following...
 #                    FindFirstFile \"C:\\Test.txt\"" );
 #         return 1;
 #     }
 #
 #     hFind = FindFirstFileA( args[ 1 ], &data );
 #
 #     if ( hFind == INVALID_HANDLE_VALUE )
 #     {
 #         writefln( "File not found or Invalid File Handle.
 #                    GetLastError reports %d", GetLastError() );
 #         return 0;
 #     }
 #     else
 #     {
 #         writefln( "The first file found is %s",  
 toString( data.cFileName ) );
 #         //writefln( "%08x %d", data.dwFileAttributes,
 #                      data.dwFileAttributes.sizeof );
 #
 #         FileTimeToSystemTime( &data.ftCreationTime, lpSystemTime);
 #         writefln( "Created=%02d/%02d/%04d %d",
 #                    systime.wDay, systime.wMonth, systime.wYear,
 #                    data.ftCreationTime.sizeof );
 #	
 #         FileTimeToSystemTime( &data.ftLastAccessTime, lpSystemTime);
 #         writefln( "Last Access=%02d/%02d/%04d %d",
 #                    systime.wDay, systime.wMonth, systime.wYear,
 #                    data.ftLastAccessTime.sizeof );
 #		
 #         FileTimeToSystemTime( & data.ftLastWriteTime, lpSystemTime);	
 #	
 #         writefln( "Last Written=%02d/%02d/%04d %d",
 #                    systime.wDay, systime.wMonth, systime.wYear,
 #                    data.ftLastWriteTime.sizeof );
 #	
 #         writefln( "%08x %d", data.nFileSizeLow,
 #                   data.nFileSizeLow.sizeof );
 #         writefln( "%s %d", toString( data.cFileName ),
 #                            data.cFileName.sizeof );
 #
 #         FindClose( hFind );
 #         return 1;
 #     }
 #
 #     return 0;
 # }

 Output in the WinXP Console:
 ----------------------------
 C:\dmd>dmd findfirstfile.d
 C:\dmd\bin\..\..\dm\bin\link.exe findfirstfile,,,user32+kernel32/noi;

 C:\dmd>findfirstfile "C:\test.txt"
 The first file found is Test.txt
 Created=12/04/2005 8
 Last Access=12/04/2005 8
 Last Written=12/04/2005 8
 0000000e 4
 Test.txt 260

 C:\dmd>findfirstfile "C:\*.*"
 The first file found is 1DPR00714.MTF
 Created=03/02/2005 8
 Last Access=01/04/2005 8
 Last Written=03/02/2005 8
 000048d2 4
 1DPR00714.MTF 260

 C:\dmd>findfirstfile "C:\*.txt"
 The first file found is Support Issue.txt
 Created=01/12/2004 8
 Last Access=18/01/2005 8
 Last Written=01/12/2004 8
 0001147d 4
 BeginNew Support Issue.txt 260

 C:\dmd>findfirstfile "C:\*.lic"
 File not found or Invalid File Handle. GetLastError reports 2

 C:\dmd>

 David L.

 -------------------------------------------------------------------
 "Dare to reach for the Stars...Dare to Dream, Build, and Achieve!"

Apr 12 2005