Extend PTE helpers with raw read and write support
This commit is contained in:
@@ -38,6 +38,7 @@ namespace MM
|
|||||||
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
||||||
XTAPI ULONG GetPpeOffset(IN PVOID Address);
|
XTAPI ULONG GetPpeOffset(IN PVOID Address);
|
||||||
VIRTUAL XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer) = 0;
|
VIRTUAL XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer) = 0;
|
||||||
|
XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
||||||
XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
||||||
XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
||||||
PMMPTE StartPte);
|
PMMPTE StartPte);
|
||||||
@@ -57,6 +58,8 @@ namespace MM
|
|||||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
IN PFN_NUMBER PageFrameNumber,
|
||||||
IN ULONG_PTR AttributesMask);
|
IN ULONG_PTR AttributesMask);
|
||||||
|
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes);
|
||||||
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
||||||
IN BOOLEAN CacheDisable,
|
IN BOOLEAN CacheDisable,
|
||||||
IN BOOLEAN WriteThrough);
|
IN BOOLEAN WriteThrough);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ namespace MM
|
|||||||
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
||||||
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
||||||
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
||||||
|
STATIC XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
||||||
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
||||||
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
||||||
PMMPTE StartPte);
|
PMMPTE StartPte);
|
||||||
@@ -53,6 +54,8 @@ namespace MM
|
|||||||
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
IN PFN_NUMBER PageFrameNumber,
|
||||||
IN ULONG_PTR AttributesMask);
|
IN ULONG_PTR AttributesMask);
|
||||||
|
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes);
|
||||||
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
||||||
IN BOOLEAN CacheDisable,
|
IN BOOLEAN CacheDisable,
|
||||||
IN BOOLEAN WriteThrough);
|
IN BOOLEAN WriteThrough);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ namespace MM
|
|||||||
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
||||||
XTAPI ULONG GetPpeOffset(IN PVOID Address);
|
XTAPI ULONG GetPpeOffset(IN PVOID Address);
|
||||||
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
||||||
|
VIRTUAL XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer) = 0;
|
||||||
XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
||||||
XTAPI ULONG GetPteOffset(IN PVOID Address);
|
XTAPI ULONG GetPteOffset(IN PVOID Address);
|
||||||
VIRTUAL XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
VIRTUAL XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
||||||
@@ -51,6 +52,8 @@ namespace MM
|
|||||||
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
IN PFN_NUMBER PageFrameNumber,
|
||||||
IN ULONG_PTR AttributesMask) = 0;
|
IN ULONG_PTR AttributesMask) = 0;
|
||||||
|
VIRTUAL XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes) = 0;
|
||||||
VIRTUAL XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
VIRTUAL XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
||||||
IN BOOLEAN CacheDisable,
|
IN BOOLEAN CacheDisable,
|
||||||
IN BOOLEAN WriteThrough) = 0;
|
IN BOOLEAN WriteThrough) = 0;
|
||||||
@@ -70,6 +73,7 @@ namespace MM
|
|||||||
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
||||||
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
||||||
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
||||||
|
XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
||||||
XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
||||||
PMMPTE StartPte);
|
PMMPTE StartPte);
|
||||||
XTAPI ULONG GetPteSize(VOID);
|
XTAPI ULONG GetPteSize(VOID);
|
||||||
@@ -83,6 +87,8 @@ namespace MM
|
|||||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
IN PFN_NUMBER PageFrameNumber,
|
||||||
IN ULONG_PTR AttributesMask);
|
IN ULONG_PTR AttributesMask);
|
||||||
|
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes);
|
||||||
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
||||||
IN BOOLEAN CacheDisable,
|
IN BOOLEAN CacheDisable,
|
||||||
IN BOOLEAN WriteThrough);
|
IN BOOLEAN WriteThrough);
|
||||||
@@ -101,6 +107,7 @@ namespace MM
|
|||||||
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
XTAPI BOOLEAN GetOneEntry(IN PMMPTE Pte);
|
||||||
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
XTAPI PFN_NUMBER GetPageFrameNumber(IN PMMPTE Pte);
|
||||||
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
||||||
|
XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
||||||
XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
||||||
PMMPTE StartPte);
|
PMMPTE StartPte);
|
||||||
XTAPI ULONG GetPteSize(VOID);
|
XTAPI ULONG GetPteSize(VOID);
|
||||||
@@ -114,6 +121,8 @@ namespace MM
|
|||||||
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
IN PFN_NUMBER PageFrameNumber,
|
||||||
IN ULONG_PTR AttributesMask);
|
IN ULONG_PTR AttributesMask);
|
||||||
|
XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes);
|
||||||
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
||||||
IN BOOLEAN CacheDisable,
|
IN BOOLEAN CacheDisable,
|
||||||
IN BOOLEAN WriteThrough);
|
IN BOOLEAN WriteThrough);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace MM
|
|||||||
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
STATIC XTAPI PVOID GetPdeVirtualAddress(IN PMMPDE PdePointer);
|
||||||
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
STATIC XTAPI PMMPPE GetPpeAddress(IN PVOID Address);
|
||||||
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
STATIC XTAPI PVOID GetPpeVirtualAddress(IN PMMPPE PpePointer);
|
||||||
|
STATIC XTAPI ULONG_PTR GetPte(IN PMMPTE PtePointer);
|
||||||
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
STATIC XTAPI PMMPTE GetPteAddress(IN PVOID Address);
|
||||||
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
STATIC XTAPI LONG GetPteDistance(PMMPTE EndPte,
|
||||||
PMMPTE StartPte);
|
PMMPTE StartPte);
|
||||||
@@ -49,6 +50,8 @@ namespace MM
|
|||||||
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
IN PFN_NUMBER PageFrameNumber,
|
IN PFN_NUMBER PageFrameNumber,
|
||||||
IN ULONG_PTR AttributesMask);
|
IN ULONG_PTR AttributesMask);
|
||||||
|
STATIC XTAPI VOID SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes);
|
||||||
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
STATIC XTAPI VOID SetPteCaching(IN PMMPTE PtePointer,
|
||||||
IN BOOLEAN CacheDisable,
|
IN BOOLEAN CacheDisable,
|
||||||
IN BOOLEAN WriteThrough);
|
IN BOOLEAN WriteThrough);
|
||||||
|
|||||||
@@ -269,6 +269,24 @@ MM::PageMap::GetPpeOffset(IN PVOID Address)
|
|||||||
return ((((ULONGLONG)Address) >> MM_PPI_SHIFT) & 0x1FF);
|
return ((((ULONGLONG)Address) >> MM_PPI_SHIFT) & 0x1FF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entire contents of a Page Table Entry (PTE) as a single value.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Pointer to the Page Table Entry (PTE) to read.
|
||||||
|
*
|
||||||
|
* @return This routine returns the contents of the PTE as a single value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG_PTR
|
||||||
|
MM::PageMap::GetPte(IN PMMPTE PtePointer)
|
||||||
|
{
|
||||||
|
/* Return PTE value */
|
||||||
|
return PtePointer->Long;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -461,7 +479,7 @@ MM::PageMap::SetOneEntry(IN PMMPTE Pte,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a PML2 page table entry (PTE) with the specified physical page and access flags.
|
* Sets a Page Table Entry (PTE) with the specified physical page and access flags.
|
||||||
*
|
*
|
||||||
* @param PtePointer
|
* @param PtePointer
|
||||||
* Pointer to the page table entry (PTE) to set.
|
* Pointer to the page table entry (PTE) to set.
|
||||||
@@ -488,6 +506,27 @@ MM::PageMap::SetPte(IN PMMPTE PtePointer,
|
|||||||
PtePointer->Long |= AttributesMask;
|
PtePointer->Long |= AttributesMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a Page Table Entry (PTE) with the specified attributes.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Pointer to the page table entry (PTE) to set.
|
||||||
|
*
|
||||||
|
* @param Attributes
|
||||||
|
* Specifies the attributes to apply to the PTE.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::PageMap::SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes)
|
||||||
|
{
|
||||||
|
PtePointer->Long = Attributes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets caching attributes for a PML2 page table entry (PTE).
|
* Sets caching attributes for a PML2 page table entry (PTE).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -301,6 +301,23 @@ MM::PageMapBasic::GetPdeVirtualAddress(IN PMMPDE PdePointer)
|
|||||||
return ((PVOID)((ULONG)(PdePointer) << 20));
|
return ((PVOID)((ULONG)(PdePointer) << 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entire contents of a PML2 Page Table Entry (PTE) as a single value.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Pointer to the Page Table Entry (PTE) to read.
|
||||||
|
*
|
||||||
|
* @return This routine returns the contents of the PTE as a single value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG_PTR
|
||||||
|
MM::PageMapBasic::GetPte(IN PMMPTE PtePointer)
|
||||||
|
{
|
||||||
|
/* Return PTE value */
|
||||||
|
return PtePointer->Pml2.Long;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Calculates the distance between two PTE pointers.
|
* Calculates the distance between two PTE pointers.
|
||||||
*
|
*
|
||||||
@@ -472,6 +489,27 @@ MM::PageMapBasic::SetPte(IN PMMPTE PtePointer,
|
|||||||
PtePointer->Pml2.Long |= AttributesMask;
|
PtePointer->Pml2.Long |= AttributesMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a PML2 page table entry (PTE) with the specified attributes.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Pointer to the page table entry (PTE) to set.
|
||||||
|
*
|
||||||
|
* @param Attributes
|
||||||
|
* Specifies the attributes to apply to the PTE.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::PageMapBasic::SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes)
|
||||||
|
{
|
||||||
|
PtePointer->Pml2.Long = Attributes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets caching attributes for a PML2 page table entry (PTE).
|
* Sets caching attributes for a PML2 page table entry (PTE).
|
||||||
*
|
*
|
||||||
@@ -650,6 +688,24 @@ MM::PageMapXpa::GetPdeVirtualAddress(IN PMMPDE PdePointer)
|
|||||||
return ((PVOID)((ULONG)(PdePointer) << 18));
|
return ((PVOID)((ULONG)(PdePointer) << 18));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entire contents of a PML3 Page Table Entry (PTE) as a single value.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Pointer to the Page Table Entry (PTE) to read.
|
||||||
|
*
|
||||||
|
* @return This routine returns the contents of the PTE as a single value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG_PTR
|
||||||
|
MM::PageMapXpa::GetPte(IN PMMPTE PtePointer)
|
||||||
|
{
|
||||||
|
/* Return PTE value */
|
||||||
|
return PtePointer->Pml3.Long;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the distance between two PTE pointers.
|
* Calculates the distance between two PTE pointers.
|
||||||
*
|
*
|
||||||
@@ -820,6 +876,27 @@ MM::PageMapXpa::SetPte(IN PMMPTE PtePointer,
|
|||||||
PtePointer->Pml3.Long |= AttributesMask;
|
PtePointer->Pml3.Long |= AttributesMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a PML3 page table entry (PTE) with the specified attributes.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Pointer to the page table entry (PTE) to set.
|
||||||
|
*
|
||||||
|
* @param Attributes
|
||||||
|
* Specifies the attributes to apply to the PTE.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::PageMapXpa::SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes)
|
||||||
|
{
|
||||||
|
PtePointer->Pml3.Long = Attributes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets caching attributes for a PML3 page table entry (PTE).
|
* Sets caching attributes for a PML3 page table entry (PTE).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -293,6 +293,24 @@ MM::Paging::GetPpeVirtualAddress(IN PMMPPE PpePointer)
|
|||||||
return PmlRoutines->GetPpeVirtualAddress(PpePointer);
|
return PmlRoutines->GetPpeVirtualAddress(PpePointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entire contents of a Page Table Entry (PTE) as a single value.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Pointer to the Page Table Entry (PTE) to read.
|
||||||
|
*
|
||||||
|
* @return This routine returns the contents of the PTE as a single value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
ULONG_PTR
|
||||||
|
MM::Paging::GetPte(IN PMMPTE PtePointer)
|
||||||
|
{
|
||||||
|
/* Return PTE value */
|
||||||
|
return PmlRoutines->GetPte(PtePointer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
* Gets the address of the PTE (Page Table Entry), that maps given address.
|
||||||
*
|
*
|
||||||
@@ -495,6 +513,27 @@ MM::Paging::SetPte(IN PMMPTE PtePointer,
|
|||||||
PmlRoutines->SetPte(PtePointer, PageFrameNumber, AttributesMask);
|
PmlRoutines->SetPte(PtePointer, PageFrameNumber, AttributesMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a Page Table Entry (PTE) with the specified attributes.
|
||||||
|
*
|
||||||
|
* @param PtePointer
|
||||||
|
* Pointer to the page table entry (PTE) to set.
|
||||||
|
*
|
||||||
|
* @param Attributes
|
||||||
|
* Specifies the attributes to apply to the PTE.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
MM::Paging::SetPte(IN PMMPTE PtePointer,
|
||||||
|
IN ULONG_PTR Attributes)
|
||||||
|
{
|
||||||
|
PmlRoutines->SetPte(PtePointer, Attributes);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets caching attributes for a PML2 page table entry (PTE).
|
* Sets caching attributes for a PML2 page table entry (PTE).
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user