Index: trunk/Include/Classes/System/IO/FileStream.ab
===================================================================
--- trunk/Include/Classes/System/IO/FileStream.ab	(revision 349)
+++ trunk/Include/Classes/System/IO/FileStream.ab	(revision 388)
@@ -1,5 +1,4 @@
 Namespace System
 Namespace IO
-
 
 /* ほんとはmiscに入れるかかファイルを分けたほうがいいかもしれないが一先ず実装 */
@@ -28,6 +27,6 @@
 	fileShare As DWord
 	fileOptions As DWord
-	fileReadOverlapped As OVERLAPPED
-	fileWriteOverlapped As OVERLAPPED
+	
+	offset As QWord 'オーバーラップドIO用
 
 Public
@@ -108,4 +107,5 @@
 		This.fileShare = sh
 		This.fileOptions = op
+		This.offset = 0
 	End Sub
 	Sub FileStream(path As String, mode As FileMode, access As FileAccess, share As FileShare)
@@ -133,10 +133,4 @@
 		This.FileStream(path,mode,access,FileShare.None,FileOptions.None)
 	End Sub
-
-	Sub ~FileStream()
-		This.Flush()
-		This.Close()
-	End Sub
-
 Public
 	Override Function CanRead() As Boolean
@@ -176,5 +170,5 @@
 	Function IsAsync() As Boolean
 		/* ファイルが非同期操作に対応しているかを返す */
-		If This.fileOptions=FILE_FLAG_OVERLAPPED/*FileOptions.Asynchronous*/ Then
+		If This.fileOptions And FILE_FLAG_OVERLAPPED /*FileOptions.Asynchronous*/ Then
 			Return True
 		Else
@@ -187,10 +181,10 @@
 			Dim length As LARGE_INTEGER
 			length.LowPart=GetFileSize(This.handle,VarPtr(length.HighPart) As *DWord)
-			Return MAKEQWORD(length.LowPart,length.HighPart)
+			Return MAKEQWORD(length.LowPart,length.HighPart) As Int64
 		End If
 	End Function
 
 	Function Name() As String
-		Return New String(This.filePath)
+		Return This.filePath
 	End Function
 	
@@ -198,8 +192,5 @@
 		If This.CanSeek() Then
 			If This.IsAsync() Then
-				fileReadOverlapped.Offset=LODWORD(value)
-				fileReadOverlapped.OffsetHigh=HIDWORD(value)
-				fileWriteOverlapped.OffsetHigh=LODWORD(value)
-				fileWriteOverlapped.OffsetHigh=HIDWORD(value)
+				offset = value As QWord
 			Else
 				Dim position As LARGE_INTEGER
@@ -213,10 +204,10 @@
 		If This.CanSeek() Then
 			If This.IsAsync() Then
-				Return MAKEQWORD(fileReadOverlapped.Offset,fileReadOverlapped.OffsetHigh)
+				Return offset As Int64
 			Else
 				Dim position As LARGE_INTEGER
 				ZeroMemory(VarPtr(position),SizeOf(LARGE_INTEGER))
 				position.LowPart=SetFilePointer(This.handle,position.LowPart,VarPtr(position.HighPart) As *DWord,FILE_CURRENT)
-				Return MAKEQWORD(position.LowPart,position.HighPart)
+				Return MAKEQWORD(position.LowPart,position.HighPart) As Int64
 			End If
 		End If
@@ -257,19 +248,16 @@
 	End Function
 
-	Override Sub Close()
-		This.Dispose()
-	End Sub
-
 /*	CreateObjRef*/
 	
-	Override Sub Dispose()
+	Override Sub Dispose(disposing As Boolean)
+		Flush()
 		CloseHandle(InterlockedExchangePointer(VarPtr(This.handle),NULL))
 	End Sub
 
-	Override Function EndRead(ByRef asyncResult As System.IAsyncResult) As Long
-		'TODO
-	End Function
-
-	Override Sub EndWrite(ByRef asyncResult As System.IAsyncResult)
+	Override Function EndRead(asyncResult As System.IAsyncResult) As Long
+		'TODO
+	End Function
+
+	Override Sub EndWrite(asyncResult As System.IAsyncResult)
 		'TODO
 	End Sub
@@ -298,22 +286,30 @@
 
 	Sub Lock(position As Int64, length As Int64)
+		If position < 0 Then
+			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(position), "position")
+		ElseIf length < 0 Then
+			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(length), "length")
+		End If
+		LockFile(handle, LODWORD(position As QWord), HIDWORD(position As QWord),
+			LODWORD(length As QWord), HIDWORD(length As QWord))
 	End Sub
 
 	Override Function Read( buffer As *Byte, offset As Long, count As Long) As Long
 		If This.CanRead() Then
-			Dim ret As DWord
-			If This.IsAsync() Then
-				ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),This.fileReadOverlapped)
-				While This.fileReadOverlapped.Internal=STATUS_PENDING
-				Wend
-				fileReadOverlapped.Offset+=LODWORD(ret)
-				fileReadOverlapped.OffsetHigh+=HIDWORD(ret)
-				fileWriteOverlapped.Offset+=LODWORD(ret)
-				fileWriteOverlapped.OffsetHigh+=HIDWORD(ret)
-				Return ret
-			Else
-				ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),ByVal NULL)
-				Return ret
-			End If
+			Dim readBytes As DWord
+			If This.IsAsync() Then
+				Dim overlapped As OVERLAPPED
+				SetQWord(VarPtr(overlapped.Offset), offset)
+				Dim ret = ReadFile(This.handle, VarPtr(buffer[offset]), count, 0, overlapped)
+				If ret = FALSE Then
+					If GetLastError() = ERROR_IO_PENDING Then
+						GetOverlappedResult(This.handle, overlapped, readBytes, TRUE)
+					End If
+				End If
+				offset += Read
+			Else
+				ReadFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(readBytes),ByVal NULL)
+			End If
+			Read = readBytes As Long
 		End If
 	End Function
@@ -326,18 +322,9 @@
 				Select Case origin
 					Case SeekOrigin.Begin
-						fileReadOverlapped.Offset=LODWORD(offset)
-						fileReadOverlapped.OffsetHigh=HIDWORD(offset)
-						fileWriteOverlapped.OffsetHigh=LODWORD(offset)
-						fileWriteOverlapped.OffsetHigh=HIDWORD(offset)
+						This.offset = offset
 					Case SeekOrigin.Current
-						fileReadOverlapped.Offset+=LODWORD(offset)
-						fileReadOverlapped.OffsetHigh+=HIDWORD(offset)
-						fileWriteOverlapped.Offset+=LODWORD(offset)
-						fileWriteOverlapped.OffsetHigh+=HIDWORD(offset)
+						This.offset += offset
 					Case SeekOrigin.End
-						fileReadOverlapped.Offset=LODWORD(This.Length()+offset)
-						fileReadOverlapped.OffsetHigh=HIDWORD(This.Length()+offset)
-						fileWriteOverlapped.Offset=LODWORD(This.Length()+offset)
-						fileWriteOverlapped.OffsetHigh=HIDWORD(This.Length()+offset)
+						This.offset = This.Length + offset
 				End Select
 			Else
@@ -379,19 +366,29 @@
 
 	Sub Unlock(position As Int64, length As Int64)
-	End Sub
+		If position < 0 Then
+			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(position), "position")
+		ElseIf length < 0 Then
+			Throw New ArgumentOutOfRangeException("FileStream.Lock: An argument is negative value.", New System.Int64(length), "length")
+		End If
+		UnlockFile(handle, LODWORD(position As QWord), HIDWORD(position As QWord),
+			LODWORD(length As QWord), HIDWORD(length As QWord))
+	End Sub
+
 
 	Override Sub Write(buffer As *Byte, offset As Long, count As Long)
 		If This.CanWrite() Then
-			Dim ret As DWord
-			If This.IsAsync() Then
-				WriteFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),This.fileWriteOverlapped)
-				While This.fileReadOverlapped.Internal=STATUS_PENDING
-				Wend
-				This.fileReadOverlapped.Offset+=LODWORD(ret)
-				This.fileReadOverlapped.OffsetHigh+=HIDWORD(ret)
-				This.fileWriteOverlapped.Offset+=LODWORD(ret)
-				This.fileWriteOverlapped.OffsetHigh+=HIDWORD(ret)
-			Else
-				WriteFile(This.handle,VarPtr(buffer[offset]),count,VarPtr(ret),ByVal NULL)
+			Dim writeBytes As DWord
+			If This.IsAsync() Then
+				Dim overlapped As OVERLAPPED
+				SetQWord(VarPtr(overlapped.Offset), offset)
+				Dim ret = WriteFile(This.handle, VarPtr(buffer[offset]), count, 0, overlapped)
+				If ret = FALSE Then
+					If GetLastError() = ERROR_IO_PENDING Then
+						GetOverlappedResult(This.handle, overlapped, writeBytes, TRUE)
+					End If
+				End If
+				offset += writeBytes
+			Else
+				WriteFile(This.handle, VarPtr(buffer[offset]), count, VarPtr(writeBytes), ByVal NULL)
 			End If
 		End If
