*******************************************************************************
///////////////////////////////////////////////////////////////////////////////
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(¬ification,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(¬ification.EventTime);
GetUserName(UserNameChar,¬ification.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,
¬ification,
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.