Ajouter un commentaire

fredericmazue

Donc c'est tout simple. Je me suis dit qu'il n'y avait pas de raisons que l'écriture dans un disque soit interdite du point de vue de la sécurité, vu que quand on peut écrire dans un volume, on peut largement faire des dégâts :)
D'un autre côté j'ai pu écrire sur un disque Linux donc non monté ni vu comme contenant des volumes par Vista.
Alors je ne sais pas si c'est voulu ou un bug de Vista, mais j'ai eu l'intuition que Vista applique la politique de la ceinture et des bretelles pour sécurisé le pantalon :lol: Avec cette politique, un lock sur le disque ne suffit pas. La solution consiste donc à ouvrir le disque et le locker, et AUSSI ouvrir les partitions sur le dit disque et les locker. Ceci étant fait, tu peux écrire où tu veux avec le HANDLE du *disque* passé à WriteFile. Je dis bien le disque.
Ci-dessous le code que j'ai bricolé à partir de mes essais d'hier. Il ouvre ma clé USB connecté en PhycisalDrive3 et comportant une seule partition montée en H: et il *écrit* dans le secteur 100, ce qui était impossible avant. Tu adapteras tout ça à ton cas. Regarde pas trop le code. Il n'est pas beau, construit à coups de copier/coller et surtout mal organisé, puisque je l'ai bricolé, mais il présente quand même l'intérêt majeur de fonctionner. :D

#include <windows.h>

#include <iostream>

using namespace std;

const DWORD sector_size = 512;
const char* volume_name = "\\\\.\\H:";
const char* disk_name = "\\\\.\\PhysicalDrive3"; // clé USB "H:"
const int target_sector = 100;

BOOL SeekSector(HANDLE disk, int sector)
{
	DWORD result = 0;
	result = ::SetFilePointer(disk,
		sector * sector_size, // Attention aux débordements!
		0, // paresse de ma part: seul les secteurs des 4 premiers Go sont accessibles
		FILE_BEGIN);
	if(result == INVALID_SET_FILE_POINTER)
	{
		cerr << "Impossible de pointer sur le secteur " << sector << endl;
		return FALSE;
	}
	return TRUE;
}


BOOL ReadSector(HANDLE disk, int sector, void* buffer)
{
	DWORD nb_read;
	BOOL result;

	SeekSector(disk, sector);
	result = ::ReadFile(disk, buffer, sector_size, &nb_read, NULL);
	if(!result)
	{
		cerr << "Impossible de lire le secteur " << sector << endl;
		return FALSE;
	}
	if(nb_read != sector_size)
	{
		cerr << "Probleme, secteur " << sector << " pas lu completement" << endl;
		return FALSE;
	}
	return TRUE;
}

BOOL WriteSector(HANDLE disk, int sector, void* buffer)
{
	DWORD nb_written;
	BOOL result;

	SeekSector(disk, sector);
	result = ::WriteFile(disk, buffer, sector_size, &nb_written, NULL);
	if(!result)
	{
		cerr << "Impossible d'ecrire le secteur " << sector << endl;
		return FALSE;
	}
	if(nb_written != sector_size)
	{
		cerr << "Probleme, secteur " << sector << " pas ecrit completement" << endl;
		return FALSE;
	}
	return TRUE;
}

int main()
{
	HANDLE disk=0;
	HANDLE volume=0;
	BOOL result;
	DWORD error;
	char* buffer[sector_size];
	
	::ZeroMemory(buffer, sector_size);
	disk = ::CreateFile(disk_name, 
		GENERIC_READ|GENERIC_WRITE,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL, // Security descriptor
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH|FILE_FLAG_OPEN_REPARSE_POINT,
		NULL);

	if(disk == INVALID_HANDLE_VALUE)
	{
		cerr << "Echec ouverture: " << disk_name <<endl;
		return 1;
	}

	volume = ::CreateFile(volume_name, 
		GENERIC_READ|GENERIC_WRITE,
		FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL, // Security descriptor
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH|FILE_FLAG_OPEN_REPARSE_POINT,
		NULL);


	cout << "Ouverture: " << disk_name <<endl;
	
	result = ReadSector(disk, target_sector, buffer);
	if(result)
	{
		DWORD returned;
		result = ::DeviceIoControl(disk, 
			FSCTL_LOCK_VOLUME,
			NULL,
			0,
			NULL,
			0,
			&returned,
			NULL);

		if(!result)
		{
			cerr << "Impossible de verrouiller " << disk_name << endl;
		}

		result = ::DeviceIoControl(volume, 
			FSCTL_LOCK_VOLUME,
			NULL,
			0,
			NULL,
			0,
			&returned,
			NULL);

		if(!result)
		{
			cerr << "Impossible de verrouiller " << disk_name << endl;
		}

		
		result = WriteSector(disk, target_sector, buffer);
		if(!result)
		{
			cerr << "Ecriture du secteur " << target_sector << " impossible" << endl;
			error = GetLastError();
		}

		result = ::DeviceIoControl(volume, 
			FSCTL_UNLOCK_VOLUME,
			NULL,
			0,
			NULL,
			0,
			&returned,
			NULL);

		result = ::DeviceIoControl(disk, 
			FSCTL_UNLOCK_VOLUME,
			NULL,
			0,
			NULL,
			0,
			&returned,
			NULL);

		if(!result)
		{
			cerr << "Impossible de deverrouiller " << disk_name << endl;
		}
		
	}

	result = ::CloseHandle(volume);
	result = ::CloseHandle(disk);
	if(!result)
	{
		return 1;

	}
	return 0;
}

Filtered HTML

Plain text

CAPTCHA
Cette question permet de vérifier que vous n'êtes pas un robot spammeur :-)
 X   X  V     V  ZZZZZ   GGG   TTTTTT 
X X V V Z G TT
X V V Z G GG TT
X X V V Z G G TT
X X V ZZZZZ GGG TT