الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[ تمت الإجابة ]الداله Ntsetinformationfile

مغلق
بدأه C++er في 5 يناير 2010 · 13 رد · 2,258 مشاهدة · في أرشيف قسم Windows APIs
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

احاول تغيير بعض اعدادات الملف بعد فتحه او انشائه بإستخدام NtCreateFile او NtOpenFile قمت بكتابة الداله التاليه و التى تقوم بتعديل حالة الحذف بعد الإغلاق للملف

bool __stdcall SetDeleteStatusAPI(IN HANDLE hFile, IN bool Status)
{
	IO_STATUS_BLOCK IoStatusBlock;
	FILE_MODE_INFORMATION ModeInfo;

	// get file mode information
	NTSTATUS RetStatus = NtQueryInformationFile
			(hFile, &IoStatusBlock, &ModeInfo,
			sizeof(ModeInfo), FileModeInformation);

	// check status
	if (!NT_SUCCESS(RetStatus))
	{
		SetLastError(RtlNtStatusToDosError(RetStatus));
		return false;
	}

	// set delete status depending on input value
	if (Status)
		ModeInfo.Mode |= DELETE;
	else
		ModeInfo.Mode &= ~DELETE;

	// set file mode information
	RetStatus = NtSetInformationFile(hFile, &IoStatusBlock,
			&ModeInfo, sizeof(ModeInfo),
			FileModeInformation);

	// if operation not succeded
	if (!NT_SUCCESS(RetStatus))
	{
		SetLastError(RtlNtStatusToDosError(RetStatus));
		return false;
	}

	/"520cooperation completed successfully
	return true;
}

المشكله انها الداله تفشل بإستمرار و القيمه المعاده دائما هى STATUS_INVALID_PARAMETER، لذا قمت بمراجعة الداله داخل وثائق WDK فلم اجد اى معلومات بخصوص امكانية تعديل الـ Mode Information لملف و لكنى لم ايأس فقمت بالبحث على الأنترنت فلم اجد شيئا حتى موقع مايكروسوفت لا يوفر معلومات كافيه لذا قمت بالحبث عن كود الداله NtSetInformationFile لويندوز 2000 و بعد ان وجدته و صلت لهذه الجزئيه

NTSTATUS
NtSetInformationFile(
    IN HANDLE FileHandle,
    OUT PIO_STATUS_BLOCK IoStatusBlock,
    IN PVOID FileInformation,
    IN ULONG Length,
    IN FILE_INFORMATION_CLASS FileInformationClass
    )
{
    .
    .
    .
    .
    .

    if (FileInformationClass == FileModeInformation) {

        PFILE_MODE_INFORMATION modeBuffer = irp->AssociatedIrp.SystemBuffer;

        //
        // Set the various flags in the mode field for the file object, if
        // they are reasonable.  There are 4 different invalid combinations
        // that the caller may not specify:
        //
        //     1)  An invalid flag was set in the mode field.  Not all Create/
        //         Open options may be changed.
        //
        //     2)  The caller set one of the synchronous I/O flags (alert or
        //         nonalert), but the file is not opened for synchronous I/O.
        //
        //     3)  The file is opened for synchronous I/O but the caller did
        //         not set either of the synchronous I/O flags (alert or non-
        //         alert).
        //
        //     4)  The caller set both of the synchronous I/O flags (alert and
        //         nonalert).
        //

        if ((modeBuffer->Mode & ~FILE_VALID_SET_FLAGS) ||
            ((modeBuffer->Mode & (FSIO_A | FSIO_NA)) && (!(fileObject->Flags & FO_SYNCHRONOUS_IO))) ||
            ((!(modeBuffer->Mode & (FSIO_A | FSIO_NA))) && (fileObject->Flags & FO_SYNCHRONOUS_IO)) ||
            (((modeBuffer->Mode & FSIO_A) && (modeBuffer->Mode & FSIO_NA) ))) {
            status = STATUS_INVALID_PARAMETER;

        } else {

            //
            // Set or clear the appropriate flags in the file object.
            //

            if (!(fileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)) {
                if (modeBuffer->Mode & FILE_WRITE_THROUGH) {
                    fileObject->Flags |= FO_WRITE_THROUGH;
                } else {
                    fileObject->Flags &= ~FO_WRITE_THROUGH;
                }
            }

            if (modeBuffer->Mode & FILE_SEQUENTIAL_ONLY) {
                fileObject->Flags |= FO_SEQUENTIAL_ONLY;
            } else {
                fileObject->Flags &= ~FO_SEQUENTIAL_ONLY;
            }

            if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
                if (modeBuffer->Mode & FSIO_A) {
                    fileObject->Flags |= FO_ALERTABLE_IO;
                } else {
                    fileObject->Flags &= ~FO_ALERTABLE_IO;
                }
            }

            status = STATUS_SUCCESS;
        }

        //
        // Complete the I/O operation.
        //

        irp->IoStatus.Status = status;
        irp->IoStatus.Information = 0L;

    }

    .
    .
    .
    .
    .
}

هذا هو الجزء الوحيد المتعلق بـ الـ FileModeInformation و مع ذلك لا يظهر اى جزء فى الكود متعلق بإختبار حالة الـ Flag تجاه الـ Delete Mode.

قد يكون استعاجلى اعمى عيني عن امر ما (كالعاده :ph34r: ) لذا يمكنك تجربة الكود الخاص بى بالأعلى :excl: او يمكنك النظر لكود الداله NtStatus :blink: او يمكنك ان تتركنى هكذا اكاد احترق غيظا :mad: او يمكنك ان تقول لماذا لا تعمل دالتى العزيزه.

مسار الداله NtSetInformationFile بكود ويندوز 2000 فى المسار التالى

\win2k\private\ntos\io\qsinfo.c

و السلام عليكم

*************************************************************************

ينهار ابيض، الداله NtQueryInformationFile دائما بترجع الـ Mode بصفر ليه مش عارف حاولت معها بكذا طريقه دائما الـ Mode بصفر.

هووف !!! انا خلاص قرفت منها محدش يعرف طريقه احول بيها لينكس و ارتاح من دوال الـ Ntxx.

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 5 يناير 2010 في 22:40

مدونتي: C++ Tips and Tricks

#2
اقتباس
1) An invalid flag was set in the mode field. Not all Create/Open options may be changed.

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#3

أخ محمد علاء الدين

من إين لك بكود ويندوز 2000 :sleep:

هذا أولا

ثانيا

من إين لى أنا أيضا بهذا الكود :happy:

تم تعديل هذه المشاركة بواسطة _- محمد نور -_ في 6 يناير 2010 في 12:28

لا إله إلا الله محمد رسول الله

アッラー以外に神はなし。ムハンマドはアッラーの使徒である

#4

انا كنت رافع الكود على استضافة عبيرالمسك الله يرحمها

هتلاقي السورس على التورنت ...

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#5

السبب كما أشار إليه GM ..

اقتباس
قمت بكتابة الداله التاليه و التى تقوم بتعديل حالة الحذف بعد الإغلاق للملف

لماذا لا تستخدم NtCreateFile او NtOpenFile بإسناد القيمة FILE_DELETE_ON_CLOSE .

طبعاً لا تنسى

اقتباس
If this flag is set, the DELETE flag must be set in the DesiredAccess parameter.
#6
اقتباس
لماذا لا تستخدم NtCreateFile او NtOpenFile بإسناد القيمة FILE_DELETE_ON_CLOSE .

كانت عندى فكره غريبه و كنت عايز اطبقها.

اقتباس
1) An invalid flag was set in the mode field. Not all Create/Open options may be changed.

انظروا هذا السطر

        // get file mode information
        NTSTATUS RetStatus = NtQueryInformationFile
                        (hFile, &IoStatusBlock, &ModeInfo,
                        sizeof(ModeInfo), FileModeInformation);

لماذا تعود الداله NtQueryInformationFile بـ FILE_MODE_INFORMATION يحتوى على الـ Mode بصفر، مهما كانت الـ CreateOptions التى وضعتها او الـ DesiredAccess فهى دائما بصفر، لذا لما تتصرف هى بهذا الشكل الغريب ؟؟؟

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#7

ما هي قيم الـNTSTATUS المرجعة ؟ هل البرنامج يعمل في الـProcess context المالك لمقبض الملف ؟

الدالة تعمل بشكل طبيعي على الملفات عندي .

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#8
GamingMasteR كتب:

ما هي قيم الـNTSTATUS المرجعة ؟ هل البرنامج يعمل في الـProcess context المالك لمقبض الملف ؟

الدالة تعمل بشكل طبيعي على الملفات عندي .

الداله تعود بـ STATUS_SUCCESS و مع ذلك فإن الـ Mode العائد منها مازال بصفر ايا كان الـ CreateOptions.

امر غريب الداله NtQueryInformationFile لاتعود بأى قيمه على الإطلاق فى حالة ان نوع البيانات المطلوب هو FILE_MODE_INFORMATION.

مدونتي: C++ Tips and Tricks

#9

على الأغلب المشكلة في القيم الممررة لـ NtCreateFile او NtOpenFile ..

في CreateOptions/ OpenOptions اضف FILE_SYNCHRONOUS_IO_NONALERT و هذا بدوره يستوجب :

إضافة SYNCHRONIZE في DesiredAccess

ضع الكود الذي إستخدمته لنتأكد ...

الكود التالي ينفذ ويعطي قيمه للـ mode

    HANDLE FileHandle;
    OBJECT_ATTRIBUTES ObjAttr;
    IO_STATUS_BLOCK IoStatus;
    UNICODE_STRING FileName;
    UNICODE_STRING DirName;
    NTSTATUS Status = STATUS_SUCCESS;  
    FILE_MODE_INFORMATION ModeInfo;
        RtlInitUnicodeString(&DirName,L"\\??\\C:\\Test.txt" );
        InitializeObjectAttributes(&ObjAttr, &DirName, OBJ_CASE_INSENSITIVE, 0, NULL);
        Status = NtOpenFile(&FileHandle,SYNCHRONIZE| FILE_GENERIC_READ,
                               &ObjAttr,
                              &IoStatus,  
                              FILE_OPEN_IF,
                              FILE_SYNCHRONOUS_IO_NONALERT);
        /*Status = NtCreateFile(&FileHandle,
                                SYNCHRONIZE| FILE_GENERIC_READ,
                              &ObjAttr,
                              &IoStatus,
                               NULL,
                               FILE_ATTRIBUTE_NORMAL,
                               FILE_SHARE_READ | FILE_SHARE_WRITE,
                               FILE_OPEN_IF,
                               FILE_SYNCHRONOUS_IO_NONALERT,
                               NULL,
                               0);*/
        // get file mode information
        NTSTATUS RetStatus = NtQueryInformationFile
                        (FileHandle, &IoStatus, &ModeInfo,
                        sizeof(ModeInfo), FileModeInformation);
        NtClose(FileHandle);
        printf("%x\n",ModeInfo.Mode);
#10

تعديل على الرد السابق

اقتباس
This structure contains a set of flags that specify the mode in which the file can be accessed. These flags are a subset of the options that can be specified in the CreateOptions parameter of the IoCreateFile routine

بعد إستدعاء NtCreateFile / NtOpenFile وإسناد قيم للـ Create/OpenOptions فإن تلك القيم (بعضها ) هي التي سنحصل عليها حين نستدعي NtQueryInformationFile ..

على الأغلب هي ليست مشكلة , انت لم تحدد Create/OpenOptions لذا فالناتج 0

هذا والله أعلم

المعذرة على الرد السابق

#11
اقتباس
على الأغلب هي ليست مشكلة , انت لم تحدد Create/OpenOptions لذا فالناتج 0

الـ OpenOptions لدى هى GENERIC_READ | GENERIC_WRITE | DELETE و الـ CreateOptions هى FILE_DELETE_ON_CLOSE و مع هذه الإعدادات مازال الـ Mode يتم استرجاعه بصفر.

عموما كل احتياجى فى هذه النقطه هو الحصول على حالة الـ Delete On Close للملف لذا قمت بإستخدام FILE_STANDARD_INFORMATION مع NtQueryInformation و النتيجه العائده اتعامل مع DeletePending و بذلك احصل على المعلومه التى احتاجها.

عموما قمت بفتح موضوع على الـ MSDN و سأضع النتيجه هنا لما توصلنا إليه هناك او ما توصلت له.

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 6 يناير 2010 في 22:35

مدونتي: C++ Tips and Tricks

#12

في هذه الحالة ستحتاج لعمل FileMonitor

capture IRP_MJ_CREATE

ومن خلال قيمة pIrpStack->Parameters.Create.Options بامكانك معرفة إذا ما كان قد تم إسناد FILE_DELETE_ON_CLOSE ..

#13

بدون ان اقوم بعمل FileMonitor، الملف فعلا يتم فتحه بـ FILE_DELETE_ON_CLOSE و الدليل على ذلك انه بعد إغلاقه يتم حذقه.

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#14
اقتباس
بدون ان اقوم بعمل FileMonitor، الملف فعلا يتم فتحه بـ و الدليل على ذلك انه بعد إغلاقه يتم حذقه

:blink:

يا عمي هو في حد قال لك انه لا يحصل هذا الشئ !!! ما هو واضح من اسمه

اقتباس
Delete the file when the last handle to it is passed to NtClose.

ما قصدته إذا ما كان ملف ما اسند له الـ FILE_DELETE_ON_CLOSE فيمكن عمل ذلك باستخدام فكرة الـ File Monitoring ...

لا أعلم إن كان هناك حل آخر ....

هذا الموضوع مغلق.

مواضيع مشابهة