ERROR_MORE_DATA occur in FilterReplyMessage for processing in preop Callback

hi to all of u… :slight_smile:

i m facing a problem related to FilterReplymessage(…)

i m using the response of FilterReplymessage(…) in a minifilter’s preop callback.

initially i did that in postop callback and get that work sucessfully executed.
i did all my postop processing in DoCompletionProcessingWhenSafe(…)

i was sending data to usermode program and got the response accordingly…

now i need to do some processing in “preop” also FltsendMessage(…) and user mode FilterGetMessage(…) works fine but
when i send the reply of message i got an error in usermode function FilterReplyMessage(…) which is ERROR_MORE_DATA HRESULT hr == 0x800700EA.

i am not able to find out why this is going wrong in Preop where the same function work correctly for postop operations.

preop callbacks are not getting the reply where as PostOp operations works fine…

please get me out of this …

hello brothers…

what happen… i did’t get even a single reply…

is it my question was wrong or did i asked that question in a wrong manner… ???

i m new to this forum…

thank u…

Usually, ERROR_MORE_DATA means that you must repeat the call with the
larger buffer provided.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntfsd…
> hello brothers…
>
> what happen… i did’t get even a single reply…
>
> is it my question was wrong or did i asked that question in a wrong manner…
???
>
> i m new to this forum…
>
> thank u…
>
>
>
>
>
>

but the point of confusion is that the same operation(FilterReplyMEssage) works sucessfully for postoperation callback…

there one problem arise that when FilterReplyMessage() function (from user mode application) return ERROR_MORE_DATA, wating driver start executing next instruction(just after FltSendMessage) with BAD or invalid Pointer return.

i cannot understand why the same operation works in PostOperation and not working in preoperation callback.

plesase help me out.

Please post the relevant code and we may be able to help you.

//Daniel

wrote in message news:xxxxx@ntfsd…
> plesase help me out.
>
>
>

*******************************************************************************
///////////////////////////////////////////////////////////////////////////////
Kernel MODE STRUCTURES AND DEFINITIONS…
///////////////////////////////////////////////////////////////////////////////
****************************************************************************

typedef struct _SCANNER_NOTIFICATION {

CHAR Operation;
ULONG Reserved; // for quad-word alignement of the Contents structure
LUID UserLogOnID;
UCHAR Contents[SCANNER_READ_BUFFER_SIZE];
ULONG ContentsSize;
BOOLEAN Open;
BOOLEAN Created;
BOOLEAN Deleted;
BOOLEAN Moved;
BOOLEAN IsRenamed;
UCHAR Renamed[SCANNER_READ_BUFFER_SIZE];
ULONG RenamedSize;
BOOLEAN Access_Denied;
BOOLEAN Read;
BOOLEAN Modified;
BOOLEAN Sec_DACL_Modify;
BOOLEAN Sec_SACL_Modify;
BOOLEAN Sec_Owner_Modify;
BOOLEAN Sec_PGroup_Modify;
BOOLEAN IsFile;
BOOLEAN IsDir;
HANDLE ProcessID;
LARGE_INTEGER EventTime;

} SCANNER_NOTIFICATION, *PSCANNER_NOTIFICATION;

typedef struct _SCANNER_REPLY {

WCHAR Drives[26];
WCHAR DRIVEGUID[50];
WCHAR SafeToOpen;

} SCANNER_REPLY, *PSCANNER_REPLY;

typedef struct _SCANNER_REPLY_MESSAGE {

SCANNER_REPLY Reply;

} SCANNER_REPLY_MESSAGE, *PSCANNER_REPLY_MESSAGE;

FLT_PREOP_CALLBACK_STATUS
MiniPreCreate (
IN OUT PFLT_CALLBACK_DATA Data,
IN PCFLT_RELATED_OBJECTS FltObjects,
OUT PVOID *CompletionContext
)
{
PFLT_FILE_NAME_INFORMATION FileI ;
NTSTATUS status;
CHAR UserNameChar[100] = {0};
SCANNER_NOTIFICATION notification;
SCANNER_REPLY_MESSAGE replyMessage;
ULONG replyLength, length;
PIO_SECURITY_CONTEXT SecurityContext ;
PSECURITY_INFORMATION pSecInf;
SECURITY_INFORMATION SecInf;
BOOLEAN SendMsg = FALSE ;
ULONG CreateDispositions;

if (FlagOn(Data->Flags,FLTFL_CALLBACK_DATA_IRP_OPERATION))
{

/////////////////////////////sending data to user mode/////////////////////////////////////////////

if (IsUserConnected == TRUE)
{

/////////////////////////initializing structure to zero /////////////////
RtlZeroMemory(&notification,sizeof(notification));
////////////////////////////////////////////////////////////////////////////

//////////////////////////mark for deletion////////////////////////////////////////////////

if( (Data->Iopb->Parameters.Create.Options & FILE_DELETE_ON_CLOSE) == FILE_DELETE_ON_CLOSE )
{
notification.Deleted = 1;
SendMsg = TRUE;
}

if (Data->IoStatus.Status == STATUS_SUCCESS)
{

/////////////filling operation specific information in message///////////////////

status = FltGetFileNameInformation(
Data,
FLT_FILE_NAME_NORMALIZED |FLT_FILE_NAME_QUERY_DEFAULT,
&FileI);

if (NT_SUCCESS(status))
{

status = FltParseFileNameInformation( FileI );
if (!NT_SUCCESS(status))
{
DbgPrint(“error in getting filename information”);

}

notification.ProcessID = PsGetCurrentProcessId();
KeQuerySystemTime(&notification.EventTime);

GetUserName(UserNameChar,&notification.UserLogOnID);
RtlCopyBytes (notification.Contents,FileI->Name.Buffer,FileI->Name.MaximumLength);
notification.ContentsSize = FileI->Name.MaximumLength;

SecInf = Data->Iopb->Parameters.SetSecurity.SecurityInformation;

notification.Operation = ‘C’;

status = FltSendMessage( ScannerData.Filter,
&ScannerData.ClientPort,
&notification,
sizeof(notification),
&replyMessage,
&replyLength,
NULL );

if (replyMessage.Reply.SafeToOpen == 65)
{
if (FileI != NULL)
FltReleaseFileNameInformation(FileI);
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
DbgPrint("\n Allowed ");

}
else
{
DbgPrint(“\n Not Allowed”);
if (FileI != NULL)
FltReleaseFileNameInformation(FileI);

Data->IoStatus.Status = STATUS_ACCESS_DENIED ;
Data->IoStatus.Information =0;
FltSetCallbackDataDirty( Data );
return FLT_PREOP_SUCCESS_NO_CALLBACK;

}

if(status == STATUS_TIMEOUT)
{
DbgPrint(“timeout”);
}
if (!NT_SUCCESS(status))
{
DbgPrint(“sending failed”);
}
else
{
DbgPrint(“sending success”);
}

if (FileI != NULL)
FltReleaseFileNameInformation(FileI);

}

}
}
}

return FLT_PREOP_SUCCESS_WITH_CALLBACK;

}

*******************************************************************************
///////////////////////////////////////////////////////////////////////////////
USER MODE STRUCTURES AND DEFINITIONS…
///////////////////////////////////////////////////////////////////////////////
****************************************************************************

typedef struct _SCANNER_NOTIFICATION {

CHAR Operation;
ULONG Reserved;
LUID UserLogOnID;
UCHAR Contents[SCANNER_READ_BUFFER_SIZE];
ULONG ContentsSize;
BOOLEAN Open;
BOOLEAN Created;
BOOLEAN Deleted;
BOOLEAN Moved;
BOOLEAN IsRenamed;
UCHAR Renamed[SCANNER_READ_BUFFER_SIZE];
ULONG RenamedSize;
BOOLEAN Access_Denied;
BOOLEAN Read;
BOOLEAN Modified;
BOOLEAN Sec_DACL_Modify;
BOOLEAN Sec_SACL_Modify;
BOOLEAN Sec_Owner_Modify;
BOOLEAN Sec_PGroup_Modify;
BOOLEAN IsFile;
BOOLEAN IsDir;
HANDLE ProcessID;
LARGE_INTEGER EventTime;

} SCANNER_NOTIFICATION, *PSCANNER_NOTIFICATION;

typedef struct _SCANNER_MESSAGE {

FILTER_MESSAGE_HEADER MessageHeader;
SCANNER_NOTIFICATION Notification;
OVERLAPPED Ovlp;

} SCANNER_MESSAGE, *PSCANNER_MESSAGE;

typedef struct _SCANNER_REPLY {

WCHAR Drives[26];
WCHAR DRIVEGUID[50];
WCHAR SafeToOpen;

} SCANNER_REPLY, *PSCANNER_REPLY;

typedef struct _SCANNER_REPLY_MESSAGE {

FILTER_REPLY_HEADER ReplyHeader;
SCANNER_REPLY Reply;

} SCANNER_REPLY_MESSAGE, *PSCANNER_REPLY_MESSAGE;

void CUserModeDlg::OnButton1()
{

AfxBeginThread(StartCapture,this);

}

UINT StartCapture(LPVOID pParam)
{
HRESULT hr;
struct _SID usersid;
CUserModeDlg *Dlg = (CUserModeDlg*)pParam;

hr = FilterConnectCommunicationPort( ScannerPortName,
0,
NULL,
0,
NULL,
&port );

if (IS_ERROR( hr ))
{
printf( “ERROR: Connecting to filter port: 0x%08x\n”, hr );
return 0;
}

while(1)
{
PSCANNER_MESSAGE msg;

SCANNER_REPLY_MESSAGE replyMessage;
PSECURITY_LOGON_SESSION_DATA sessionData = NULL;
NTSTATUS retval;

//
// Allocate the message.
//

msg = (PSCANNER_MESSAGE)malloc( sizeof( SCANNER_MESSAGE ) );

if (msg == NULL) {

hr = ERROR_NOT_ENOUGH_MEMORY;
return 0;
}

memset(&(msg->Notification),0,sizeof(msg->Notification));
memset( &msg->Ovlp, 0, sizeof( OVERLAPPED ) );

//
// Request messages from the filter driver.
//

hr = FilterGetMessage( port,
&msg->MessageHeader,
FIELD_OFFSET( SCANNER_MESSAGE, Ovlp ),
NULL);

if (hr != 0)
{

free( msg );
continue;

}

//////////////////////////////////////////////////////////////////////
////////////////////get process name and path/////////////////////////

/////////////////////GET USER NAME ///////////////////////////////////

//////////////////////////////////////////////////////////////////////
////////////////////////////SEND reply////////////////////////////////

replyMessage.ReplyHeader.Status = 0;
replyMessage.ReplyHeader.MessageId = msg->MessageHeader.MessageId;

int reply = AfxMessageBox(L"allow this operation",MB_OKCANCEL);

if (reply == IDOK)
{
wcscpy(&(replyMessage.Reply.SafeToOpen),L"A");
}
else
{
wcscpy(&(replyMessage.Reply.SafeToOpen),L"N");

}

hr = FilterReplyMessage( port,
(PFILTER_REPLY_HEADER) &replyMessage,
sizeof( replyMessage ) );

if (IS_ERROR(hr)) ///////>>>****here come that error for preoperation callback******

{
DWORD error_code = GetLastError();

}

free(msg);
}

CloseHandle(port);
return 0 ;

}

i have used the same code ( by changing return type and few modification not related to message) in postop callback in safe completion … but here in preop i have done it directly… it is giving error_more_data…

i could not undrstand why a buffer size sucessfully work for post-op where the same did’t work in pre-op… buffers are fixed size…as u can see them from definitions.

If this is all your code then you are calling FltSendMessage without having
intialized ReplyLength, which should be set
to the size of the reply buffer. The error code you are seeing is
STATUS_BUFFER_OVERFLOW and not ERROR_MORE_DATA.

//Daniel

wrote in message news:xxxxx@ntfsd…
> status = FltSendMessage( ScannerData.Filter,
> &ScannerData.ClientPort,
> &notification,
> sizeof(notification),
> &replyMessage,
> &replyLength,
> NULL );
>

thanks for reply…

but
replylength is already initialised as ULONG replyLength, it is not a pointer .

ULONG replyLength, length;
PIO_SECURITY_CONTEXT SecurityContext ;
PSECURITY_INFORMATION pSecInf;
SECURITY_INFORMATION SecInf;
BOOLEAN SendMsg = FALSE ;
ULONG CreateDispositions;

whatever the grabage value it have … it is an OUT parameter and this should be initialised by a sucessfull FilterReplyMessage()…

a sucessful FilterReplyMessage() fill values in replyMessage and replyLength variables…

if i m wrong on these please correct me…

thank u.

Declared but not initialized, that’s something else:
replyLength=sizeof (replyMessage);

You are right that it is confusing that a parameter with only an OUT
specifier should have been initialized on input. However this is behavior is
persistent in the WDK and I have no idea why.

//Daniel

wrote in message news:xxxxx@ntfsd…
> thanks for reply…
>
> but
> replylength is already initialised as ULONG replyLength, it is not a
> pointer .
>
>
> ULONG replyLength, length;
> PIO_SECURITY_CONTEXT SecurityContext ;
> PSECURITY_INFORMATION pSecInf;
> SECURITY_INFORMATION SecInf;
> BOOLEAN SendMsg = FALSE ;
> ULONG CreateDispositions;
>
>
> whatever the grabage value it have … it is an OUT parameter and this
> should be initialised by a sucessfull FilterReplyMessage()…
>
> a sucessful FilterReplyMessage() fill values in replyMessage and
> replyLength variables…
>
> if i m wrong on these please correct me…
>
> thank u.
>

hi Daniel,

i tried as u sugessted but still im getting the same error… User mOd program gives ERROR_MORE_DATA in FilterReplyMessage() where Driver INVALID_POINTER in FltSendMessage().

same thing is working perfectly For PostOperation Callback… i m doing my Post operation in safe IRQL level, where as in Pre-op i m simply calling those functions, as Preoperation callbacks are guranteed to be called in PASSIVE_LEVEL or APC_LEVEL …

i am not getting any clue about this probelm… documentation is very low and as this error type is concerned information is extreamly low…

i m wating for ur reply…

thank you…

Set a breakpoint on FilterReplyMessage. Hook up Windbg and set a breakpoint
on FltSendMessage. In your driver, analyze replyLength before and after the
call to FltSendMessage. Check the values you are getting and compare that to
the value of ReplyBufferSize in FilterReplyMessage. For more suggestions
check Laiqs thread above.

//Daniel

wrote in message news:xxxxx@ntfsd…
> hi Daniel,
>
>
> i tried as u sugessted but still im getting the same error… User mOd
> program gives ERROR_MORE_DATA in FilterReplyMessage() where Driver
> INVALID_POINTER in FltSendMessage().
>
> same thing is working perfectly For PostOperation Callback… i m doing
> my Post operation in safe IRQL level, where as in Pre-op i m simply
> calling those functions, as Preoperation callbacks are guranteed to be
> called in PASSIVE_LEVEL or APC_LEVEL …
>
> i am not getting any clue about this probelm… documentation is very
> low and as this error type is concerned information is extreamly low…
>
> i m wating for ur reply…
>
> thank you…
>
>
>

thank u

i i finally found the problem… as u said …

your words were true … i made few modification and it works as it should …

thanks a lot mr. Daniel…
:slight_smile:
i m happy now