ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

id_badblock.cpp
Go to the documentation of this file.
00001 /*++
00002 
00003 Copyright (C) 2006 VorontSOFT
00004 
00005 Module Name:
00006     id_badblock.cpp
00007 
00008 Abstract:
00009     This is the artificial badblock simulation part of the
00010     miniport driver for ATA/ATAPI IDE controllers with Busmaster DMA support
00011 
00012 Author:
00013     Nikolai Vorontsov (NickViz)
00014 
00015 Environment:
00016     kernel mode only
00017 
00018 Notes:
00019 
00020     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00021     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00022     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00023     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00024     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00025     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00026     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00027     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00029     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 
00031 Revision History:
00032     2006/08/03 Initial implementation.
00033     2006/08/06 Added registry work.
00034     2007/03/27 Added device serial to registry value name instead of LUN.
00035 
00036 --*/
00037 
00038 #include "stdafx.h"
00039 
00040 //#define MAX_BADBLOCKS_ITEMS 512
00041 
00042 
00043 
00044 //SBadBlockRange    arrBadBlocks[MAX_BADBLOCKS_ITEMS];
00045 //ULONG            nBadBlocks = 0;
00046 
00047 LIST_ENTRY BBList;
00048 BOOLEAN BBListInited = FALSE;
00049 
00050 // RtlQueryRegistryValues callback function
00051 static NTSTATUS __stdcall
00052 BadBlockQueryRoutine(
00053     IN PWSTR ValueName,
00054     IN ULONG ValueType,
00055     IN PVOID ValueData,
00056     IN ULONG ValueLength,
00057     IN PVOID Context,
00058     IN PVOID EntryContext
00059     )
00060 {
00061     PSBadBlockListItem cur;
00062     PLIST_ENTRY      link;
00063     ULONG i;
00064     // The ValueType should be REG_SZ
00065     // The ValueData is UNICODE string of the following format:
00066     //  "badblocks_start_from_lba  badblocks_end_at_lba"
00067 
00068     KdPrint(( "BadBlockQueryRoutine: S/N:%S\n type %#x, len %#x\n", ValueName, ValueType, ValueLength));
00069 
00070     if(!BBListInited)
00071         return STATUS_SUCCESS;
00072 
00073     if((ValueType == REG_BINARY)  &&            // STRING
00074         ValueLength &&            // At least "0 0 0"
00075         !(ValueLength % sizeof(SBadBlockRange)))    // There is free space for the record
00076     {
00077         cur = NULL;
00078         link = BBList.Flink;
00079         while(link != &BBList) {
00080             cur = CONTAINING_RECORD( link, SBadBlockListItem, List);
00081             link = link->Flink;
00082             if(!wcscmp(cur->SerNumStr, ValueName)) {
00083                 KdPrint(( "already loaded\n"));
00084                 if(cur->LunExt) {
00085                     cur->LunExt->nBadBlocks   = 0;
00086                     cur->LunExt->arrBadBlocks = NULL;
00087                     cur->LunExt->bbListDescr  = NULL;
00088                     cur->LunExt = NULL;
00089                 }
00090                 break;
00091             }
00092         }
00093 
00094         if(!cur) {
00095             cur = (PSBadBlockListItem)ExAllocatePool(NonPagedPool, sizeof(SBadBlockListItem));
00096             if(!cur)
00097                 return STATUS_SUCCESS;
00098         } else {
00099             if(cur->arrBadBlocks) {
00100                 ExFreePool(cur->arrBadBlocks);
00101                 cur->arrBadBlocks = NULL;
00102             }
00103         }
00104         cur->arrBadBlocks = (SBadBlockRange*)ExAllocatePool(NonPagedPool, ValueLength);
00105         if(!cur->arrBadBlocks) {
00106             ExFreePool(cur);
00107             return STATUS_SUCCESS;
00108         }
00109         RtlCopyMemory(cur->arrBadBlocks, ValueData, ValueLength);
00110         wcsncpy(cur->SerNumStr, ValueName, 127);
00111         cur->SerNumStr[127] = 0;
00112         cur->nBadBlocks = ValueLength/sizeof(SBadBlockRange);
00113         cur->LunExt = NULL;
00114         InitializeListHead(&cur->List);
00115         InsertTailList(&BBList, &(cur->List));
00116         for(i=0; i<cur->nBadBlocks; i++) {
00117             KdPrint(( "BB: %I64x - %I64x\n", cur->arrBadBlocks[i].m_lbaStart, cur->arrBadBlocks[i].m_lbaEnd-1));
00118         }
00119     }
00120     return STATUS_SUCCESS;
00121 } // end BadBlockQueryRoutine()
00122 
00123 
00124 void
00125 NTAPI
00126 InitBadBlocks(
00127     IN PHW_LU_EXTENSION LunExt
00128     )
00129 {
00130     RTL_QUERY_REGISTRY_TABLE QueryTable[2];    // Main record and zero filled end of array marker
00131     WCHAR DevSerial[128];
00132 #ifdef _DEBUG
00133     UCHAR cDevSerial[128];
00134     ULONG i;
00135 #endif
00136     ULONG Length;
00137     PLIST_ENTRY      link;
00138     PSBadBlockListItem   cur;
00139     // Read from the registry necessary badblock pairs and fill in arrBadBlocks array
00140     // HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\UniATA\Parameters\BadBlocks
00141 
00142     if(!LunExt) {
00143         // init
00144         KdPrint(( "InitBadBlocks general\n"));
00145         if(!BBListInited) {
00146             InitializeListHead(&BBList);
00147             BBListInited = TRUE;
00148         }
00149 
00150         QueryTable[0].QueryRoutine    = BadBlockQueryRoutine;
00151         QueryTable[0].Flags           = RTL_QUERY_REGISTRY_REQUIRED;
00152         QueryTable[0].Name            = NULL;   // If Name is NULL, the QueryRoutine function 
00153                                                 //  specified for this table entry is called 
00154                                                 //  for all values associated with the current 
00155                                                 //  registry key. 
00156         QueryTable[0].EntryContext    = NULL;
00157         QueryTable[0].DefaultType     = REG_NONE;
00158         QueryTable[0].DefaultData     = 0;
00159         QueryTable[0].DefaultLength   = 0;
00160 
00161         RtlZeroMemory(QueryTable + 1, sizeof(RTL_QUERY_REGISTRY_TABLE));    // EOF
00162 
00163         NTSTATUS status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,
00164                                                 L"UniATA\\Parameters\\BadBlocks",
00165                                                 QueryTable, 0, 0);
00166 
00167 #ifdef _DEBUG
00168         KdPrint(( "InitBadBlocks returned: %#x\n", status));
00169 #else
00170         UNREFERENCED_PARAMETER(status);
00171 #endif
00172     } else {
00173 
00174         KdPrint(( "InitBadBlocks local\n"));
00175         Length = EncodeVendorStr(DevSerial, (PUCHAR)LunExt->IdentifyData.ModelNumber, sizeof(LunExt->IdentifyData.ModelNumber));
00176         DevSerial[Length] = '-';
00177         Length++;
00178         Length += EncodeVendorStr(DevSerial+Length, LunExt->IdentifyData.SerialNumber, sizeof(LunExt->IdentifyData.SerialNumber));
00179 
00180 #ifdef _DEBUG
00181         KdPrint(( "LunExt %#x\n", LunExt));
00182         for(i=0; i<Length; i++) {
00183             cDevSerial[i] = (UCHAR)(DevSerial[i]);
00184         }
00185         KdPrint(( "S/N:%s\n", cDevSerial));
00186 #endif
00187 
00188         LunExt->nBadBlocks = 0;
00189         LunExt->arrBadBlocks = NULL;
00190 
00191         link = BBList.Flink;
00192         while(link != &BBList) {
00193             cur = CONTAINING_RECORD( link, SBadBlockListItem, List);
00194             link = link->Flink;
00195             if(cur->LunExt == LunExt) {
00196                 KdPrint(( "  deassociate BB list (by LunExt)\n"));
00197                 cur->LunExt->nBadBlocks   = 0;
00198                 cur->LunExt->arrBadBlocks = NULL;
00199                 cur->LunExt->bbListDescr  = NULL;
00200                 cur->LunExt = NULL;
00201             } else
00202             if(!wcscmp(cur->SerNumStr, DevSerial)) {
00203                 KdPrint(( "  deassociate BB list (by Serial)\n"));
00204                 if(cur->LunExt) {
00205                     cur->LunExt->nBadBlocks   = 0;
00206                     cur->LunExt->arrBadBlocks = NULL;
00207                     cur->LunExt->bbListDescr  = NULL;
00208                     cur->LunExt = NULL;
00209                 }
00210             }
00211         }
00212 
00213         if(!(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE)) {
00214 
00215             link = BBList.Flink;
00216             while(link != &BBList) {
00217                 cur = CONTAINING_RECORD( link, SBadBlockListItem, List);
00218                 link = link->Flink;
00219                 if(!wcscmp(cur->SerNumStr, DevSerial)) {
00220                     KdPrint(( "found BB:List\n"));
00221                     cur->LunExt = LunExt;
00222                     LunExt->arrBadBlocks = cur->arrBadBlocks;
00223                     LunExt->nBadBlocks   = cur->nBadBlocks;
00224                     LunExt->bbListDescr  = cur;
00225                     return;
00226                 }
00227             }
00228         }
00229     }
00230     return;
00231 } // end InitBadBlocks()
00232 
00233 
00234 void
00235 NTAPI
00236 ForgetBadBlocks(
00237     IN PHW_LU_EXTENSION LunExt
00238     )
00239 {
00240     if(LunExt->bbListDescr) {
00241         LunExt->bbListDescr->LunExt = NULL;
00242         LunExt->nBadBlocks   = 0;
00243         LunExt->arrBadBlocks = NULL;
00244         LunExt->bbListDescr  = NULL;
00245     }
00246 } // end ForgetBadBlocks()
00247 
00248 bool
00249 NTAPI
00250 CheckIfBadBlock(
00251     IN PHW_LU_EXTENSION LunExt,
00252 //    IN UCHAR command,
00253     IN ULONGLONG lba,
00254     IN ULONG count
00255     )
00256 {
00257     if (LunExt->nBadBlocks == 0)
00258         return false;
00259 /*
00260     // this is checked by caller
00261     if(!(AtaCommandFlags[command] & ATA_CMD_FLAG_LBAsupp)) {
00262         return false;
00263 */
00264     ULONG nBadBlocks = LunExt->nBadBlocks;
00265     SBadBlockRange*  arrBadBlocks = LunExt->arrBadBlocks;
00266 
00267     // back transform for possibly CHS'ed LBA
00268     lba = UniAtaCalculateLBARegsBack(LunExt, lba);
00269 
00270     for (ULONG i = 0; i < nBadBlocks; i++)
00271     {
00272         if (lba + count > arrBadBlocks->m_lbaStart  &&  
00273                     lba < arrBadBlocks->m_lbaEnd) {
00274             KdPrint(( "listed BB @ %I64x\n", lba));
00275             return true;
00276         }
00277         arrBadBlocks++;
00278     }
00279 
00280     return false;
00281 
00282 } // end CheckIfBadBlock()

Generated on Sat May 26 2012 04:26:56 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.