‫Hello and welcome back, everybody.
‫In the last lecture, we implemented the virtual filesystems f open.
‫In this lecture, we're going to implement that sixteen's open so that we can actually open 16 files.
‫OK, so follow what I'm doing.
‫In fact, 16 open.
‫We're going to say if Moad does not equal Follmer reads, then we will return an error.
‫OK, and if we just scroll up, we're going to include Colonel Hatch and we also need to go to status
‫state as well, guys, because we need to correct that definition.
‫So e read-only e are the only.
‫OK, so let me just explain that a moment.
‫We're not going to implement writing in our file system, at least not at first.
‫We may get to that later in the course, but it's more complicated.
‫So we're going to try and keep this as simple as possible so that you can learn things relating to call
‫operating system development.
‫File system development is kind of a branch of OS step I want to teach you.
‫Operating system development as a whole.
‫OK, so let's continue.
‫The next step is to create a structure fat file descriptor.
‫And we'll call this Descript, and it will be an points pointer for now and then down here we're going
‫to say descript equals Kasar log size of struct fat file scripter.
‫OK, I guess you could all put that on the one line if you wanted, but I'm going to keep it like that.
‫And you'll notice is complaining about this structure incomplete type not allowed.
‫That's because I miss about something earlier on.
‫So if we just scroll up.
‫And you'll see item descriptor, it should actually be faithful to script, so I misplaced the words
‫when we wrote that structure.
‫So fat file descriptor guys not fight, not fat item descriptor.
‫So you can see that's now resolved that problem.
‫And when now going to say if we failed to create the memory for the descriptor then return error minus
‫e nomen.
‫OK, and now here we're going to say just scripter pass equals zero, because obviously when you first
‫opened the file, the stream is going to be at the first byte in the file.
‫Right.
‫So that's why we said pass to zero here.
‫And now, finally here, we're just going to say return to scripter.
‫So that is our first 16 function, essentially.
‫But we're not quite done because there's another thing we have to do.
‫Online, three or five, we need to say descriptor.
‫Item equals fat 16, get directory item to get direct entry, I mean, and we haven't created this function
‫yet and we're going to pass in the disk and the path.
‫OK, now here we're going to say if the scripter item is no, i.e. we couldn't find it, then we're
‫going to return and area because that means they couldn't find the file.
‫We couldn't find the file, basically.
‫So what's happening here then?
‫We allocate the memory for the Farad's a script.
‫We look in the Fat 16 file system to see if we can find that file with the given path.
‫OK, now this function will return the fat item.
‫OK, this fat 16 get directory entry will literally return a fat item and a fat item describes either
‫a directory or a normal file.
‫Right.
‫So we'll look for that for us.
‫And then if it finds the file, it'll create a fat item and it'll set it here.
‫So we set the scripter item to the one that the fat and get directory entry returns.
‫And obviously we set the position to zero.
‫As I explained, files should stop from offset zero.
‫We're reading from the beginning and then we just return the descriptor.
‫OK.
‫And, you know, this is a descriptive private data, as you know.
‫And we go to file that C that's going to cause descriptive private data to be set because Fat 16 open
‫return.
‫Does that private data that we just returned here, this descriptor, and essentially we then create
‫a real descriptor in the generic virtual file system and we set the private to the private data that
‫Fat 16 returned.
‫OK, so that's how that's all working.
‫So we now need to imprint the fat 16, get directory entry function, which will ensure that we can
‫actually open files in the real fat 16 file system.
‫Essentially, it's going to look for the file on the disk if it can't find it to return null.
‫If it can find it, it'll create a fat item which describes the item that it's found.
‫And obviously, if we scroll up, you can see the fat item is essentially a union that contains a directory
‫or a directory item and a type.
‫So that that's how that works, guys.
‫So, yeah, next step now, guys, is to implement Fat 16, get directory entry, and then we are done
‫with Fat 16 open.
‫All right, let's create the fat 16 get directory entry function.
‫So just by here, we're going to go struct fat item fat 16, get directory entry and we're going to
‫struct desk desk struct path paths path.
‫And when now going to go struct FAPE private, FAPE, private equals desk, EFS, private.
‫Struct fat item current item ICA's zero struct fat item route item equals fat 16 find item in directory.
‫And again, we haven't created this function yet and we're going to go disc ampersand, fat private
‫root directory.
‫And then we're going to go path paths, so let me just explain this to you so far, so essentially the
‫fat 16 fine diamond directory function will look for an item in the given directory that we pass it
‫here and it'll expect a part of a path to also be provided and it will find that element.
‫So that's how that works.
‫OK, so this route item, you can expect it to be the first item that is found in the root directory
‫here.
‫So, for example, if we had something like zero tests at 60, then test of 60 would be would be the
‫path part and it will return a fat item for test subjects.
‫OK.
‫However, if the directory was zero A.B.C. test of Texte, then this route item would be A, B, C,
‫OK, so the fat item here would be A, B, C, which would represent a directory.
‫And obviously we're not done with this function.
‫We have to go further into this function now so that we can go through all of the path paths until we
‫find the file we're looking for, which is test object in this example.
‫So all we now need to say is we need to say if the root item is null, then there's no directory or
‫there's no file.
‫So, for example, if they if they did the ABC test t, then this would return null.
‫If the ABC directory didn't exist, if it was just zero tests at 60, then this would return null if
‫the test text file didn't exist.
‫So that's what we're going to do that.
‫I was just going to say go to out, OK?
‫And we're going to create an out label down here and we'll just return the current item.
‫That's what we'll do here.
‫OK.
‫OK, so before we continue any further, we need to create the fact 16 find item in directory function.
‫So just by here then we're going to go struct fat item fat 16 find item in directory struct desk struct
‫fat directory.
‫And this is the directory we're searching in by the way for the file, all the directory.
‫And now here comes the name.
‫So, yes, essentially, back to our example here, the very first path will be the string A, B, C,
‫so that is what is passed here on this final argument.
‫OK, and then we will try to resolve the ABC directory, for example.
‫I'm just going to zoom out a little bit here so you can see a little a little clearer.
‫Perfect, so you can see that's how the prototype should look.
‫OK, I'm going to zoom back in for you guys now, so it's easier to to read.
‫OK, so let's let's begin employing this function.
‫So we're going to go struct fat item F item equals no char temp filename and we're just going to go
‫Peatross max path.
‫Now go to kernel that Hajjaj.
‫And no conflict at each side and we're going to define that, so we're going to go define PCOS Mac's
‫path and that will be 108 bites.
‫This will be the maximum length of a path in our colonel.
‫OK, back to fat 16 DOT.
‫See, we can see that's now resolved and we're going to go for Insha I zero I below directory total
‫I plus plus.
‫So we're looping through all of the items in the directory now.
‫That's what we're doing now guys.
‫Now one thing to note, this whole directory is loaded into memory already, not the not the actual
‫file data but the actual file names and stuff like that.
‫They're already loaded into memory.
‫So that's good news for us.
‫So what we're going to do then we're going to go for 16 gets full relative file name, and we haven't
‫created this function yet.
‫And we're going to literally pass in the directory item.
‫OK, and actually it should it should look like this myristic like this.
‫OK, so the directory item with the index I we passed the address for that.
‫Now here we're going to go temp file, name size of temp filing.
‫OK, so what this is going to do, this is going to take in our directory item and it's going to resolve
‫the full relative file name for us.
‫So, for example, let's pretend we have the filename test and the extension texte.
‫Then this gatefold relative farming will return test T into temp filename.
‫That's what that's going to do.
‫OK, because remember, the file name and the extension are separate in the specification.
‫If I click here for directory item, you can see file names.
‫A bite's extension is three bytes and any unused bytes are padded with spaces.
‫Now, that doesn't make it easy for us to work with, which is why we need to create that function,
‫which will get us the full relative following.
‫OK, so just above here, we're going to say void fat 16 to proper string.
‫Sha asterisk, asterisk in, and we're going to go while asterisk in does not equal zero zero zero and
‫asterisk in does not equal zero 20.
‫And remember, we're actually accessing these these characters here.
‫We're using askaris to access the point.
‫OK, let me go ask us to ask this out.
‫Equals asterisk in asterisk outs plus equals one in plus equals one.
‫So now finally down here, we're going to say if Asterisk N is equal to zero x 20, then asterisk because
‫out equals zero zero zero.
‫That's what we're going to do here.
‫So let me explain this function to you then.
‫Essentially, this function will go through a string and it'll look for a space or an old Terminator.
‫And what it's found them will stop what it's doing.
‫And as an old Terminator, where that space was, if it was a space, that is OK.
‫So that's that's how that is working.
‫So, for example, they're going to be passing us a file name that's terminated with a space because
‫unus bytes are padded with spaces.
‫So, for example, our file names eight bytes.
‫Right?
‫So we would actually have something like one, two, three, four, five, six, seven, eight.
‫So there will be another three spaces also here, right?
‫We don't want that.
‫So by by calling this function, we end up with file and it's just an old Terminator at the end.
‫We don't have these spaces.
‫And in this example, file is the file name.
‫OK, so that's what this functions fall, guys.
‫So it's very important and it's a simple function, but we need it.
‫So now we're going to create the function that converts the given directory file, name and extension
‫into a full file name, basically the gatefold relative file name function we made here.
‫So we're going to go void fat 16 gets full relative file name and that's going to take effect.
‫Directory item.
‫A child pointed to the out and a max length.
‫So we're going to go set out zero zero zero max length.
‫So we just set the output buffer to completely nulls and I were going to say char out, temp equals
‫out and now we're going to say fat 16 to prop a string, which is the function we just made.
‫And we're going to go ampersand out temp because this is the variable.
‫This is the point where we're changing.
‫Right.
‫And then we're going to say comes char item farming.
‫So again, this will take our filename.
‫One, two, three, four, five.
‫And it'll just give us an alternative version rather than one with spaces.
‫OK, so that's what that that function is doing, remember?
‫So now we say if item extension zero does not equal zero zero and the item extension zero does not equal
‫zero 20, then we must have an extension on this file name.
‫So we're going to go ask this out.
‫Temp plus plus equals dot.
‫OK, which will put a dot because file extensions, they have dots, don't they?
‫We have the file name than a dot than the extension.
‫That's how it works.
‫And now we're going to go fat 16 to prop proper string again and we're going to go ampersand out ten
‫consed and we're going to do a cast now.
‫Consumer item.
‫OK, so that's it.
‫So this function will take a fat directory item.
‫It'll take its file, name and extension and join them together with a with a full stop here.
‫So if the file names tests and the extension is A, B, C, then this function will generate test on
‫ABC into outpoint by here.
‫OK, so that's what that is doing.
‫OK, so now that function is working correctly, we can continue.
‫We're now going to say if eyestrain string and compare temp file, name, name, size of temp file name
‫equals zero.
‫Then we have found a matching filenames, so it does exist and we can use it, so we say found it,
‫let's create a new fat item so we go find them equals fat 16 new fat item for directory item.
‫OK, and we go desk and ampersand directory item I.
‫OK, now here we go.
‫Return F item.
‫Now we need to create this function.
‫Fat 16 new fat item for directory item that needs to be created next.
‫OK, so don't be fooled because there's still quite a lot to go here and it's and it is difficult.
‫Stay with it and you'll, you'll soon understand.
‫Just pay attention.
‫So we're going to create that function.
‫Now New Fatime for director Adam.
‫So we go struct fat item fat 16, new fat item for directory item struct desk struct fat directory item
‫item.
‫So now we go struct fat item f item equals kasar block size of struct fat item.
‫So remember I told you the fat item is either a directory or file.
‫OK, that's what it is.
‫OK, so just don't get confused with that.
‫So now we're going to say if we fail to allocate the memory for the fat item then we're just going to
‫return now.
‫OK, otherwise we're going to say does the attribute of the directory item pass to us?
‫Have the.
‫Philes subdirectory flag, OK, and its attributes, because if it does, and then this fat directory
‫item that's on desk represents a subdirectory, not a normal file.
‫So that needs to be accounted for, which is why we check for that flag, OK?
‫So if it is, then we go fight him directory equals fat 16, low fat directory and there's another function
‫we got to make.
‫So that allowed the fat directory basically and we say F item type equals fat item type directory.
‫Now, if it's not a subdirectory, then it must be a file.
‫So we go fight some type equals fat item type file and we go find some item equals fat 16 Klown directory
‫item item size of struct.
‫Fat directory item, so essentially we can't rely on the item they provided to us here because we didn't
‫create that memory, it might get deleted or freed and then we could have serious memory issues because
‫of that.
‫So to get around this problem, we clone the directory item.
‫We may see copy its memory into a new directory item, and we call that function Fat 16 clone directory
‫item.
‫However, that means that we are responsible for freeing this memory at a later time.
‫So we'll have to have some sort of close function or free function that they can call us and we will
‫free the directory item.
‫So here we go.
‫Return F item.
‫OK, so we're going to create low fat directory now, which is quite complicated.
‫And we also need to implement Fat 16 clone directory item, which is easy.
‫So I'll tell you what, we're going to implement the clone directory first because it's easier functions.
‫So go struct fat directory item fat 16.
‫Clone directory item struct.
‫Fat directory, item, item and size.
‫Excellent.
‫So we're going to extract fat directory item, item, copy because Kasar lock size of struct fat directory
‫item.
‫And I'll tell you what, no, that should actually be size, so down to size.
‫We're going to do size by here and then we're going to go.
‫If the item can't be as bad, then go to out.
‫Otherwise, men copy it and copy item size.
‫Now, down here, we're going to have our return item copy.
‫Yes, sir.
‫Simply put, this will clone the directory item based on the size we provided.
‫And, you know, we can also write something here to ensure that their passing is a valid size.
‫So let's do that here as well.
‫If size is below size of struct fat directory item, then there's an error and we should go out.
‫But then that also means the item copy needs to go at the top by here.
‫So we go out and copy his Kosilek size.
‫But this one needs to go up here and we need to set it to zero.
‫OK, perfect.
‫And because of the way this works, you can even just go return item copy or return zero because that
‫there's no need to go there at this point in time.
‫So there we are.
‫That works absolutely fine.
‫No problem.
‫And yes, we can do the same here as well, guys.
‫We can just go return zero, return zero or return item copy.
‫And we won't need the outlay label then because we only really need the labels.
‫If we're dealing with memory management, stuff like that, then we need to worry about stuff like this.
‫OK, if we want to have more clauses under here, then maybe we would use go to because we might have
‫had memory allocated at that time and then obviously we need to clean it up or we'd have a memory leak
‫if there was an error.
‫So, OK, so we've implemented that that will clone any directory item.
‫We give it, including arrays of directory items.
‫OK, so let's now create the low fat directory function, so we're going to go struct fat directory,
‫fat 16 load fat directory struct desk struct, fat directory item item and we're going to go and address
‫equals zero struct fat directory directory equals zero struct fat private fat private equals desk aifs
‫private.
‫And I was going to say if.
‫The item.
‫Attribute is not a directory.
‫Then rest sequel's E invalid arguments, and we're going to go to this just to find the label down here
‫and we're just going to return directory here.
‫So in other words, we don't want them passing us files.
‫This is for loading directories.
‫If they pass us a fat directory item, that's a file.
‫What can we do with that?
‫We're trying to load a directory here, so that's why we do that check here.
‫So we're now going to go directory Eco's Kasar log size of struct fat directory.
‫If directory does not exist, we couldn't create the memory there was a problem, then rest sequel's
‫in a memory out of memory, go to out.
‫OK, so now things are going to get a bit complicated.
‫We need to do some more math, so we need to calculate the cluster.
‫So we're going to go in it cluster.
‫It was five 16 GEP first cluster item.
‫So let's look at the first cluster of the item.
‫So because they passed us in a directory here, we resolved the first cluster of wethers.
‫Directory contents are, in other words, where the directory file names are stored.
‫Well, essentially more Morphet directory items.
‫So this cluster here is the cluster of where the directory items are listed to understand for this subdirectory.
‫So now we're going to say in a cluster sector and we're going to go for that 16 cluster dissector and
‫we're going to pass in the private here along with our cluster.
‫So this will get us the sector number of the cluster essentially here.
‫We're going to go in it.
‫Total items equals five 16.
‫Get total items for directory.
‫We've already made that function.
‫So we're going to pass in the desk and the cluster sector.
‫Now we're going to go directory total equals total items in it.
‫Directory size equals directory total plus size of struct five directory item.
‫Because of course, as I've said, the subdirectories are essentially just an array of fat directory
‫items, which is why we that which is why the directory sizes is the directory total multiplied.
‫Not plus change that cluster multiply.
‫Is the directory total multiplied by the directory item.
‫OK, so that's why.
‫So now we're going to go directory item equals K like directory size.
‫So we're making enough room in memory now to load that entire directory into memory.
‫So now we're going to say if directory item does not exist, then response.
‫Sequenom, we run out of memory, go to outs.
‫So when are we going to say Rascal's Fat 16 read internal.
‫We haven't created this function yet and we're going to provide the desk the cluster zero zero zero
‫directory size and the directory item.
‫I'll explain more on that later.
‫But essentially it reads from the disk, OK, it reads that directory into memory for us starting at
‫the cluster.
‫We provide it here.
‫So now we're going to say if REST's does not equal Peatross s all, OK, then go to out.
‫And then in here we're going to say if wrests does not equal Peko s all OK then.
‫Fat 16 free directory directory.
‫OK, that's a mouthful.
‫So this, this will load the entire fat directory.
‫So simply put, we go through here, we get the cluster of the item, we get the cluster sector, we
‫get the total items in the directory and then we read.
‫From this cluster, the the size specified in directory size, now fat 16 internal, this is going to
‫be a very special function because as I said in the file allocation table, you have the fat tables,
‫you have one primary and one backup, usually the backups, the optional.
‫Now, remember, in the presentation, I told you that that there's numbers that point to the next cluster
‫while our fat 16 read internal function will take that into account.
‫So it will allow us to read an infinite amount of bytes that we want while till the end file, I guess
‫by specifying only the first cluster fat 16, which in turn will then use the file allocation table
‫to find the next cluster for us automatically.
‫So this function means that we don't have to worry about calculating any of that stuff because we do
‫it in the fat read internal function.
‫So it's probably the most important function of our Fat 16 file implementation, but that also means
‫it's one of the hardest to implement.
‫OK, so let's start by implementing these functions.
‫We're going to start with fat 16 plus to dissect.
‫So just up here, we're going to say static in it, fat 16, cluster dissector.
‫And that's going to take in a fat private and a cluster number.
‫Now we're going to go return private group directory DOT and Insec to pass plus plus minus two multiplied
‫by private header.
‫Primary header.
‫That sector sector is, I mean, per cluster.
‫OK, so that's what that's going to do and I'm going to explain that now.
‫I'm going to zoom out so you can see again, because it gets a bit tricky when when it goes off the
‫screen.
‫So, OK, so what this is doing then, OK, it takes off and in sector position and then it adds the
‫end in sector position of the root directory, I should say.
‫And then it adds that our cluster number minus two multiplied by the sectors per cluster, and that
‫takes us directly to the sector that this cluster represents.
‫Now in the file allocation table one, we want to convert clusters to sector.
‫We have to minus two from it.
‫Read the manual for further understanding of why that is.
‫But yes, that will take any cluster number and it will convert it to a sector for us.
‫And as you know, our cluster data starts after the root directory, which is why we take in the end,
‫the sector position, ending sector position of the root directory.
‫OK, so now for the first cluster functions.
‫So we're going to go Statik Unit 32 t fat 16 get first cluster and this is going to set a directory
‫item.
‫And we're then going to return item high, 16 bits of the first, Kluster odd with the low sixteen bits.
‫So essentially that just takes our high 16 bits and our low sixteen bits and it joins them together.
‫That's all of that function does, guys, because you can see we have our high 16 bits here and allow
‫16 bits here.
‫So we join them together in this way and that's how that works.
‫OK, everybody, we're now going to create the fat 16 read internal function.
‫So just by here we're going to say static and fat 16 read internal.
‫That's going to accept a desk, a starting cluster and offset a total on an out variable.
‫So this function is going to take the starting cluster and it's going to read X amount of bytes from
‫that cluster.
‫If it exceeds the cluster size, then it will look in the file allocation table for the next cluster
‫and read from that one.
‫So allows us to read as if all of the clusters are just one giant file when they're actually not.
‫So this function is very powerful because it'll mean that we won't have to do this calculation out of
‫this function.
‫So we're going to create it.
‫Now, if you're a little confused, don't worry, because more makes sense as we carry on.
‫So we're going to go struct private, first private.
‫And I'm going to zoom in for you guys here because it might be a bit hard if you're on your phone.
‫OK, there we go.
‫First private equals disc, EFS, private.
‫Struck this string
‫string equals their Privette.
‫Cluster right string and address equals fat 16 reed internal from string disc stream starting cluster
‫offset total and out.
‫So we're now going to just go return address.
‫So yeah, essentially we're going to create this fat 16 reading signal from string function.
‫Now, as a matter of fact, you know what?
‫We don't need to create the respirable.
‫Just go return fat 16 bredon cell from string.
‫That's much cleaner, I think.
‫So we're now going to implement the fat 16 reading signal from stream function.
‫So just go static and add Fat 16 reading from string
‫and we're going to accept the disc.
‫We're going to accept a disk stream,
‫a cluster and offset the total amount of bytes we want to read and an out pointer.
‫OK.
‫Now, this function is complicated.
‫So bear with me.
‫We're going to go in.
‫It equals zero return address struct fat preverb Privette equals disc aifs Privette in its size of cluster
‫bytes.
‫Equals Private Head Start, primary head sectors per cluster multiplied by desk sector size, and now
‫we're going to go in a cluster to use equals fat 16 get cluster for offset.
‫And we're going to have to implement that function, by the way, desk cluster offset.
‫So if the cluster to use is below zero, then the response is equal to the cluster to use.
‫And we're going to go to and we'll have an out label down here, guys.
‫OK, before we continue any further, we're going to implement Fat 16, get cluster for offset.
‫So just above here, we're going to go Statik in it.
‫Fat 16 get cluster for offset struck desk desk and its starting cluster and it offset.
‫So this is going to get the correct cluster to use based on the starting cluster.
‫And the offset.
‫OK, so we're going to go in and rescue 010 versus.
‫Struct for private private equals desk EFS private in its size of cluster bytes.
‫Equals private header to our primary, Haddad's sector, supercluster.
‫Multiplied by dissector size, and we may change this to a separate function because we also do something
‫similar here.
‫But for now, we'll keep it the same and we're going to go in it, Kluster, to use equal starting cluster
‫and it clusters ahead equals offset divided by size of cluster bytes.
‫And now we're going to go for it.
‫I cruzeiro i below cluster's ahead I plus plus now we're going to go in at entry equals 16 get fat entry
‫and we haven't created that function yet.
‫I will go desk cluster to use and I were going to say here, if the entry is equal to zero x FFA, all
‫the entries equal to zero x f f then we are at the last entry in the file.
‫Or the subdirectory or something like that, so he goes mansio, go to out and we're going to have an
‫out lable down here as well, guys.
‫So let me just explain this to you.
‫We're going to get the fat entry from the file allocation table here, OK?
‫And this is the cluster number we're trying to get the first entry for.
‫So this entry is either going to equal to the next entry in the file, the next cluster in the file,
‫or it's going to equal to some sort of error flag or in the file like, OK.
‫That's why we do this check here to check if it's the last entering file and there'll also be bad sectors
‫and stuff like that.
‫This dysfunction here can also return that.
‫So we need to check for that too, which we'll get to.
‫But that's all I want to know right now.
‫Essentially, clusters can have multiple clusters, you understand?
‫So we have a file that's two clusters in size.
‫Then in the file allocation table, the first cluster will have the ID of the next cluster to use.
‫We know where the last cluster one, that fat file allocation table entry is equal to Efate or FNF.
‫So I suggest you read the fat manual if you're still confused and also check back at the presentation
‫for the file allocation table because I show you how that works.
‫This is what we're doing programmatically right now.
‫We're doing exactly what is shown in the presentation.
‫So we're going to have to implement Fat 16, get fat entry and then we can continue this.
‫OK, so just above here, we're going to go static in it.
‫Fat 16, get fat entry struct desk desk and it cluster.
‫Now we're going to go in at equals minus one struck fat private private equals F as private struct this
‫stream string equals private fat read stream.
‫Now if the stream is null we're going to go to our have seven out label down here and we're just going
‫to return.
‫OK, now we're going to go unit 32 t fat table position equals five 16 GEP first fat sector, which
‫we haven't implemented yet.
‫And we're going to pass the private there and we're going to multiply it by the sector size.
‫OK, so that'll take us to the very first fat table.
‫And we're just going to implement the fat 16 GEP, first fat sack to function now.
‫So that's a very easy function.
‫Just by here, we're going to go Statik unit thirty two T fat sixteen gabfests, fat sector struck fat
‫private private return private had a primary, had a defensive sectors.
‫And we know that the very first file allocation table comes directly after the reserved sectors.
‫That's why this function works.
‫So the fat table position is at the end of the reserved sectors multiplied by the sector size.
‫OK, so now we're going to go rest's equals this stream of seke stream fat table position multiplied
‫by Kluster.
‫Multiplied by each OS, fat 16, fat entry size, OK, and we can see that the entry size is two bites
‫because this is fat 16.
‫So remember, remember the table in the presentation, the file allocation table, where you have those
‫two bytes to represent each cluster in that giant table.
‫Remember, I explained this in the presentation.
‫Check back if you if you're confused because this is complicated.
‫So now we're going to say if the rest is below zero, then we fail to seek and we should go out.
‫Otherwise we're going to go unit 16 t results equals zero.
‫Rest equals just remarried, string ampersand results, size of results.
‫And we're going to say if rest is below zero, go to our otherwise restfully equal result.
‫OK, so that is our fat 16 get fat entry function.
‫So that's how that works.
‫So it'll go into our file allocation table and it will pull out the correct fat entry and then we can
‫check that value to do what we want with it.
‫OK, so that's how that works.
‫So let's go back to Fat 16, get cluster for offset because we can continue this function now.
‫OK, so down here.
‫We're going to check if the sector is marked as bad.
‫If the entry is equal to us five 16 bad sector, then rescues minus will go to.
‫So a bad sector is like on the desk, maybe it's broken, right?
‫Maybe that sector is damaged.
‫We come right to it or rip from it.
‫So we mark the file allocation table to basically say this class is corrupted so that we don't go and
‫try and read from it or write to it again.
‫OK, so that's what that's about.
‫So now we now need to check for reserve sectors.
‫So if entry is equal to zero five zero or entry is equal to zero x four six, OK, race equals minus
‫zero.
‫Go to.
‫And if our entry is also equal to zero, then we can assume the file allocation table is corrupted and
‫we'll just go equals minus Scio go to out.
‫And the reason being is because we're looking for a cluster for the given offset.
‫And if every returns zero here, well then there was no cluster.
‫Understand, because because the first two clusters are ignored and the fat 16 we start the cluster
‫no higher than that.
‫So that doesn't make sense if it's zero here.
‫OK, so we just return an error and we're going to go a cluster to use equals entry.
‫And there we go.
‫Oh, and one more thing down here.
‫We're going to go rest's equals cluster to use OK, X and so that is our cluster for offset function.
‫OK, so back to the Fat 16 Reading Channel from string function.
‫And just down here we're going to go in it offset from cluster equals offset modulus.
‫Size of cluster bites and the modulus operator will basically allow us to easily calculate the offset
‫from the cluster.
‫So if I just open Python, I can show you this.
‫If we do four nine six modulus four nine six, we get zero.
‫If we do four nine seven, modula modulus four nine six, we get one, you see.
‫So here we calculate enough so that one.
‫So that's how Modulus works.
‫Guys is a very powerful feature of the C programming, language and mathematics.
‫So here we're going to go in it.
‫Starting cluster equals fat 16 cluster to sector and we're going to pass in the private here and then
‫we're going to pass passing cluster to use here.
‫Now we're going to go in its starting path equals starting sector on guys.
‫My mistake, this starting cluster on line four four four.
‫I meant starting sector.
‫OK, so that's what that should be because we do cluster dissector.
‫OK, so now back here in line for four five, we're going to multiply that by the disk sector size and
‫then we're going to multiply that by the offset from the cluster.
‫So we're now going to go in it total to read equals total above size of cluster bytes.
‫And we're going to have Tenebrae here, size of cluster bytes total.
‫So if the total is above the size of the cluster bytes, then we should only use the size of cluster
‫bytes, otherwise we should use the total they provided to us.
‫This is because we can only read up to a cluster at a time due to fat sixteen's design.
‫If we want to read more than one cluster, we have to go into the file allocation table and find the
‫next place to read.
‫So that's why we are doing this cap by here.
‫So we'll only ever read the size of the cluster bytes.
‫But then what if they want to read, I don't know, two clusters worth or three clusters worth maybe
‫three and a half clusters worth.
‫Well, that's fine because we're getting to that.
‫We'll only read up to one cluster at a time, but we will keep track of what's left to read so we can
‫process it later on.
‫You'll see now.
‫So we're going to go rascal's this streamer sike.
‫Stream starting position, if rest below zero, there's an error.
‫Go to our.
‫And now we're going to say REST's equals jet stream arete stream out told to read.
‫If rest is not equal, pitch us all.
‫OK, then go to out and I'll tell you I'll also change this one here.
‫Testa's two does not equal us all.
‫OK, ok.
‫OK, so now down here, we're going to go total minus equals total serried, so this suggests the total,
‫the total provided to us and now we're going to save the total is above zero.
‫Then we still have more to read and we go rest equals Fat 16 Reading Channel from Stream.
‫Desk stream, cluster offset plus total to reads.
‫Total.
‫Outs plus total to read.
‫So let me just zoom out here so you can see that a little better.
‫So this is how that's working.
‫OK, we go in here, we read up to a maximum of the class to size the maximum class size, whatever
‫total is left, we call ourselves again adjusting offset by what we've just read and adjusting our output
‫buffer by what we've just read.
‫And we pass in the total because of this recursion.
‫It will work.
‫It will load every single byte that we ask for unless we run out of stack memory, of course.
‫But that's not a concern in this case.
‫Well, it's a valid concern to worry about that, but not in not in an educational context like this.
‫So that is our first 16 Reading Channel from Stream Function.
‫So that works perfectly fine.
‫OK, so what we now need to do is we need to create the fat 16 free directory function.
‫So just by here, we're going to go void fat 16, free directory struct fat directory directory.
‫And we're going to say if the directory is null, then just return because we have nothing to free.
‫Otherwise, if the directory has an item, which is Bwelle free that free the directory item, basically
‫the directory item array.
‫Now we finally do free directory and that's fat 16 free directory function.
‫OK, guys, so we have another thing we need to do.
‫We need to implement meme copy.
‫So just go to memory that see, and we're going to implement copy here.
‫So what we're going to do is we're going to go void main copy void, dest void source in it Len.
‫And now we're going to go char d equals dast char s equal source while Len minus minus as Cristie plus
‫plus equals askaris s plus plus.
‫Now here we're going to go over Dast so that's our while copy function.
‫OK, and that will copy.
‫The memory.
‫From source to destination.
‫OK, so now we're going to copy the men copy prototype into memory DOT Hage.
‫OK, let's go back to Fat 16 and we're just going to check everything over, make sure that there's
‫nothing else to do.
‫Yes or no, we're not actually done yet, go back to Fat 16, get direct entry because we haven't finished
‫this function, so we need to go straight path part.
‫Next part, XPath, next.
‫Current item equals route item, while next part does not equal zero.
‫Current item type does not equal fat item type directory, then current item equals zero break struct
‫fat item temp item equals fat sixteen find item in directory desk current item directory.
‫Next part POCs.
‫Now we're going to go fat sixteen.
‫Fat item free, which we haven't created yet, current item, current item equals Temperton, next parts
‫equals next part's next.
‫OK, so let's just go over this so I can explain this to you then.
‫So we get the rude item, which I explained earlier on in this video, how that worked and how we basically
‫say, is there more items in our path that we need to read?
‫And if that's true, then we go in here.
‫And if our current item is not a directory, then the past is invalid because it's trying to access
‫a file as a directory.
‫Right.
‫So we go current item equals zero and we break out of this guadaloupe.
‫Otherwise we then find the next item in that current item.
‫So it could be a directory or a file.
‫OK.
‫And then we free the old one because we don't need the old one anymore, so that's how that works,
‫guys, OK?
‫And eventually we get so far down that we get to the file that we wanted.
‫So that's how that's working.
‫So let's implement that 16 item free access to do that.
‫We're just going to go here.
‫Well, at the very top, actually, let's search for fat 16 free directory.
‫So we're going to we're going to put it just below this one, OK?
‫And we're going to go void fat 16, fat item free struct, fat item item.
‫And then we're going to say if the item type is equal to the fat item type directory, then we're offering
‫a directory.
‫So we go fat 16 free directory because we're free in the directory.
‫Right.
‫So we go item directory and that's what we do.
‫That else, if the item type is a file, then we're offering a file.
‫So we go, OK, free item, item.
‫I remember we're just freeing memory.
‫We're not actually deleting files on disk or anything like that.
‫We're just freeing memory.
‫OK, else panic.
‫And we haven't implemented panic yet.
‫OK, we don't have to worry about that.
‫We'll just assume the types valid for now.
‫So down here we're going to just go caffery item.
‫So that frees up our item essentially guys.
‫OK, OK.
‫Now let's go to Canada.
‫Let's see.
‫We're going to get rid of this perfect thing here from last lecture.
‫We're just going to go in it.
‫F.T. equals f open zero.
‫Hello, thought Texte.
‫And then we're just going to go read and I was going to say fifty prints we opened.
‫Hello that texte.
‫OK, now if we get open to the terminal again and we're going to clear, we're going to clean, we're
‫going to build that S.H. Now we're going to go Sidibé and we're going to go Kumu.
‫System I 386, hey, stop, stop, stop, and look what it says, we opened.
‫Duct tape.
‫Now let's change it to hello to talk you, which doesn't exist.
‫And we should see that message disappear.
‫So make clean bill to the S.H. Cribben kumu.
‫And now we don't see that message anymore.
‫So we've now successfully implemented half open and I hope and check the local desk to see if it if
‫the file actually exists.
‫And it does this by calling our fat 16 functionality.
‫So let's just go over this quickly.
‫If we go to Fat 16 F open, fat 16 open, I should say, we go in here, we create a file descriptor
‫and then we go fat sixteen, get direct entry.
‫This looks for the file on the desk.
‫OK, we go in here, it finds our route item.
‫So in our case we only have Hello Texte.
‫So it will find that and create a fat item for it.
‫And now we've resolved it essentially.
‫Right.
‫I'm fat sixteen find item in directory.
‫This sloops through the entire directory and compares the names.
‫So you know this is, it's pretty simple, it's just time consuming to implement these things.
‫But the most important thing about this lecture is these read internal functions that we created because
‫these read internal functions will allow us to read from data from any amount of sectors now, any amount
‫of clusters, I mean, any amount it could be for file data, subdirectories, anything we like.
‫So the fact that we've done these these functions means that the reading process should be a lot simpler
‫going forward.
‫So thanks for watching this lecture.
‫You've now implemented the Fat Sixteen F Open.