Click here to Skip to main content
15,886,812 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello guys,
I posted in morning about how can I read specific address from the file, and CPallini had answered me and the solution he gave me worked.

Now, the problem is when I use SetPointerEx twice I got this error "ERROR_INVALID_PARAMETER", I read in msdn about it and msdn gave me what the problem is but msdn didn't gave me how can I solve it.

Here is my code in MASM32:
C++
PUSH	NULL                                        ; /hTemplateFile = NULL
	PUSH	FILE_ATTRIBUTE_NORMAL               ; |Attributes = FILE_ATTRIBUTE_NORMAL
	PUSH	OPEN_EXISTING                       ; |Mode = OPEN_EXISTING
	PUSH	0                                   ; |pSecurity = NULL
	PUSH	FILE_SHARE_READ + FILE_SHARE_WRITE  ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
	PUSH	GENERIC_ALL                         ; |Access = GENERIC_ALL
	PUSH	FileName                            ; |FileName = "*.exe"
	CALL	CreateFileA			    ; \CreateFileA

	MOV		hFile,EAX

	PUSH	0                                   ; /pFileSizeHigh = NULL
	PUSH	hFile                               ; |hFile = hFile
	CALL	GetFileSize			    ; \GetFileSize

	CMP		EAX, 0h
	JZ		Exit

	PUSH	FILE_BEGIN				; /dwMoveMethod = FILE_BEGIN
	PUSH	NULL					; |lpNewFilePointer = NULL
	PUSH	03Ch					; |liDistanceToMove = 03Ch
	PUSH	hFile					; |hFile = hFile
	CALL	SetFilePointerEx			; \SetFilePointerEx

	MOV		BytesToRead, 04h

	PUSH	0					; /pOverlapped = NULL
	LEA		EAX, pBytesRead
    PUSH	EAX					; |pBytesRead = ?
	PUSH	BytesToRead				; |BytesToRead = 04h
	LEA		EAX, Buffer
	PUSH	EAX					; |Buffer
	PUSH	hFile					; |hFile = hFile
	CALL	ReadFile				; \ReadFile

	MOV		EAX, Buffer
	MOV		PEsig, EAX

	MOV		EAX, PEsig
	ADD		EAX, 028h

	PUSH	FILE_BEGIN				; /dwMoveMethod = FILE_BEGIN
	PUSH	NULL					; |lpNewFilePointer = NULL
	PUSH	EAX 					; |liDistanceToMove = PEsig + 28h
	PUSH	hFile					; |hFile = hFile
	CALL	SetFilePointerEx			; \SetFilePointerEx
	
	MOV		BytesToRead, 04h

	PUSH	0					; /pOverlapped = NULL
	LEA		EAX, pBytesRead
    PUSH	EAX					; |pBytesRead = ?
	PUSH	BytesToRead		        	; |BytesToRead = 04h
	LEA		EAX, Buffer
	PUSH	EAX					; |Buffer
	PUSH	hFile					; |hFile = hFile
	CALL	ReadFile				; \ReadFile
	
	MOV		EAX, Buffer
	MOV		EntryPoint, EAX

	PUSH	hFile					; /hObject = hFile
	CALL	CloseHandle				; \CloseHandle


In first call the function works prefectly but in the second call the error occured.

According to this link
"If the hFile handle was opened with the FILE_FLAG_NO_BUFFERING flag set, an application can move the file pointer only to sector-aligned positions. A sector-aligned position is a position that is a whole number multiple of the volume's sector size. An application can obtain a volume's sector size by calling the GetDiskFreeSpace function. If an application calls SetFilePointerEx with distance-to-move values that result in a position that is not sector-aligned and a handle that was opened with FILE_FLAG_NO_BUFFERING, the function fails, and GetLastError returns ERROR_INVALID_PARAMETER. For additional information, see File Buffering."

And I have see the next link
"Alignment and File Access Requirements
As previously discussed, an application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING. The following specifics apply:
File access sizes, including the optional file offset in the OVERLAPPED structure, if specified, must be for a number of bytes that is an integer multiple of the volume sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1,024, 1,536, or 2,048 bytes, but not of 335, 981, or 7,171 bytes.
File access buffer addresses for read and write operations should be physical sector-aligned, which means aligned on addresses in memory that are integer multiples of the volume's physical sector size. Depending on the disk, this requirement may not be enforced."

So, How can I solve the problem? how can I achieve these requirements? What should I do?
Posted
Updated 7-May-13 20:34pm
v2
Comments
Jochen Arndt 8-May-13 3:33am    
You did not open the file with the flag FILE_FLAG_NO_BUFFERING. So the posted text does not apply here.

ERROR_INVALID_PARAMETER occurs when you are calling Windows API functions with wrong parameters. While specific parameters like file handles have their own error codes when invalid, others have not and this error is returned. With SetFilePointerEx(), this error should occur when passing an undefined value for dwMoveMethod. The only resaon for this error in your code might be passing a negative distance with FILE_BEGIN, but I'm not sure about this (while negative distances are allowed they might be not allowed with FILE_BEGIN).
Rasool Ahmed 8-May-13 3:41am    
First, I have used FILE_FLAG_NO_BUFFERING, and this make the first call of SetFilePointerEx fails with the error ERROR_INVALID_PARAMETER.
Second, liDistanceToMove in the second call of SetFilePointerEx equals to 100h which means is not negative. And I used FILE_CURRENT but and liDistanceToMove is larger which means that the pointer will be forward and the problem still same.
Third, I didn't understand the operation fully. There are alot of ambiguous things in SetFilePointerEx I can't specify it.
Jochen Arndt 8-May-13 3:52am    
The posted code did not use FILE_FLAG_NO_BUFFERING. If this flag is used, the first call to SetFilePointerEx() will fail because 3Ch is not a sector aligned position.

According to the missing flag in your code and that you said the error occurs in the second call, I believed that the flag is not used.
Rasool Ahmed 8-May-13 3:57am    
What shell I do to get rather from this error and proceed my work?
Do I use FILE_FLAG_NO_BUFFERING or not?
If I used this flag, what shell I do to get rather from this error?
What aligned sector means?
Jochen Arndt 8-May-13 3:59am    
See my solution for the error.

In general, I would not use the flag if not really necessary for some reasons.

1 solution

You are using SetFilePointerEx() which expects a LARGE_INTEGER (64 bit) as distance parameter but pushes only a 32 bit word on the stack.

Because you are reading from the begin of the file, using SetFilePointer() might be sufficient.
 
Share this answer
 
Comments
Rasool Ahmed 8-May-13 3:58am    
I have read about these two function but there no big difference between them, is there?
Jochen Arndt 8-May-13 4:05am    
The difference is the distance parameter which is LONG with SetFilePointer() and LARGE_INTEGER with the Ex function and the new file pointer parameter points also to a LONG resp. LARGE_INTEGER.

Using the Ex function, you can move the pointer by distances above +/-2 GB and retrieve the new pointer for files greater 4 GB.
Rasool Ahmed 8-May-13 11:51am    
Thanx Jochen Arndt, the function works now :) thanx alot.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900