Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Block-device drivers - how to handle Hard-disks ?

0 views
Skip to first unread message

R.Wieser

unread,
Nov 15, 2001, 1:28:26 PM11/15/01
to
Hello All,

I've got a nice question or two for all those people who still know what
DOS is :-)

I'm trying to write a Block-device driver that will be able to read/write a
Hard-disk. At the moment I'm able to read from the Hard-disk (my driver
reads the C: -drive).

But there is something bothering me : the BPB.

1) At Initialisation I have to return a pointer to an array-of-BPB's, and in
my case this array has got but a single BPB. This BPB however is
meaningless, because it does not (can not) match the actual layout of my HD.

So, can I disregard this pointer (set it to 0000:0000 for example, or just
do not load it) ? Extra info : the Attributes of my device-driver tells the
OS that my drive is a Non-IBM -type : it does not use/work with the FAT-ID
byte.

2) The CREATEBPB function (command-code 2) of my driver reads the BPB off
the drive, stores it, and returns the pointer to this stored BPB to the OS.
Do I really have to store the BPB ? In other words : does the local
BPB-data have to survive the next call to my Device-driver ?

Regards,
Rudy Wieser

debs

unread,
Nov 15, 2001, 4:33:46 PM11/15/01
to
Hello cyberfolk!

On Thu, 15 Nov 2001 19:28:26 +0100, R.Wieser spake thus:

>Hello All,
>
> I've got a nice question or two for all those people who still know what
>DOS is :-)

DOS? What's that? :洞

>1) At Initialisation I have to return a pointer to an array-of-BPB's, and in
>my case this array has got but a single BPB. This BPB however is
>meaningless, because it does not (can not) match the actual layout of my HD.

The BPB for a FAT partition contains only information about the
partition, not the whole drive. I'm not sure if you realise that,
based on your wording :) For a FAT partition, you read BPB from the
boot sector, and then you determine the size of the partition and some
other information based on that.

Did you read the boot sector from the correct point, or are you
reading the first sector on the physical drive? If you are reading
sector 1 of the drive, you need to read the partition table to find
the start of the partition you want to get the inforamtion for. You
then read the BPB and store the necessary information in a structure
defined by yourself in the driver.


>
>So, can I disregard this pointer (set it to 0000:0000 for example, or just
>do not load it) ? Extra info : the Attributes of my device-driver tells the
>OS that my drive is a Non-IBM -type : it does not use/work with the FAT-ID
>byte.

You ahve to load it from the disk in order to read the information. If
the driver is telling you that the drive is not an IBM drive, I'm not
clear what you are looking for or how? The drive doesn't ahve to ahve
FAT partitions in order to be IBM compatible. However, if it isn't a
FAT partition that you are trying to view, you will ahve to determine
the parameters for the aprtition from the partition table, as the BPB
is part of a FAT boot sector (I'm sure some other file system uses a
simialr system, but I don't know which if any).


>
>2) The CREATEBPB function (command-code 2) of my driver reads the BPB off
>the drive, stores it, and returns the pointer to this stored BPB to the OS.
>Do I really have to store the BPB ? In other words : does the local
>BPB-data have to survive the next call to my Device-driver ?
>

It is up to you, as the programmer, to determine whether you want to
store the BPB or just the information from it which is relevant to
your driver. For ease of use later on, you would be advised to store
at least the start cylinder and the size of the partition, otherwise
you would ahve to read this from the disk next time and interpret the
relevant parts of the BPB (or partition table).

I'm not sure why a command to read a BPB is called CreateBPB' though,
that name implies that you are creating a BPB to be part of a boot
sector (at least, it does to me) :)

>Regards,
> Rudy Wieser
>
>


debs
de...@dwiles.nospam.demon.co.uk

If you can't be kind, at least have the decency to be vague.

R.Wieser

unread,
Nov 16, 2001, 9:52:31 AM11/16/01
to
debs <de...@spamfree.net> schreef in berichtnieuws
q6c8vtcsl9h0ii7cp...@4ax.com...

Hello Debs,

> Hello cyberfolk!
>
> On Thu, 15 Nov 2001 19:28:26 +0100, R.Wieser spake thus:
>
> >Hello All,
> >
> > I've got a nice question or two for all those people who still know
what
> >DOS is :-)
>
> DOS? What's that? :洞
>
> >1) At Initialisation I have to return a pointer to an array-of-BPB's, and
in
> >my case this array has got but a single BPB. This BPB however is
> >meaningless, because it does not (can not) match the actual layout of my
HD.
>
> The BPB for a FAT partition contains only information about the
> partition, not the whole drive. I'm not sure if you realise that,
> based on your wording :)

Yes, I do. I see that my wording is somewhat un-clear :-(

> For a FAT partition, you read BPB from the
> boot sector, and then you determine the size of the partition and some
> other information based on that.

In the above, when I said HD, I actually tried to say was "any kind of
storage-media, as small as 360 KB, or as big as 40 GB. Either removable or
non-removable". In other words : The actual media does not have to be
accessable by the driver yet (think of PCMCIA-cards, that can be placed or
removed "hot"), so it's BPB is not known.

> Did you read the boot sector from the correct point, or are you
> reading the first sector on the physical drive? If you are reading
> sector 1 of the drive, you need to read the partition table to find
> the start of the partition you want to get the inforamtion for. You
> then read the BPB and store the necessary information in a structure
> defined by yourself in the driver.

Yes, I've taken the offset to the logical drive into account. Proove of
that (for me) is that I can read the Root-directory of the targetted
(logical) disk.

> >So, can I disregard this pointer (set it to 0000:0000 for example, or
just
> >do not load it) ? Extra info : the Attributes of my device-driver tells
the
> >OS that my drive is a Non-IBM -type : it does not use/work with the
FAT-ID
> >byte.
>

> You have to load it from the disk in order to read the information. If


> the driver is telling you that the drive is not an IBM drive, I'm not
> clear what you are looking for or how?

Well, my specs tell me that DOS tries to determine the geometry of the drive
from the MEDIA-ID byte. When this NON-IBM -bit is set, DOS will directly
request the BPB (command-code 2) from the device-driver

> The drive doesn't have to have


> FAT partitions in order to be IBM compatible. However, if it isn't a

> FAT partition that you are trying to view, you will have to determine
> the parameters for the partition from the partition table, as the BPB


> is part of a FAT boot sector (I'm sure some other file system uses a

> similar system, but I don't know which if any).


> >
> >2) The CREATEBPB function (command-code 2) of my driver reads the BPB off
> >the drive, stores it, and returns the pointer to this stored BPB to the
OS.
> >Do I really have to store the BPB ? In other words : does the local
> >BPB-data have to survive the next call to my Device-driver ?
> >
> It is up to you, as the programmer, to determine whether you want to
> store the BPB or just the information from it which is relevant to
> your driver. For ease of use later on, you would be advised to store
> at least the start cylinder and the size of the partition, otherwise
> you would ahve to read this from the disk next time and interpret the
> relevant parts of the BPB (or partition table).

None of the information in the BPB is relevant to my driver : I'm using
"Large-disk" functions (like INT 13, AH=42h) that look at the drive as
having a large array of blocks, not heads-tracks-sectors.

But DOS uses the BPB information. And I'm not sure if DOS copies the BPB I
stored into my driver, or just keeps a pointer to it (which forces to keep
it available at all times).

> I'm not sure why a command to read a BPB is called CreateBPB' though,
> that name implies that you are creating a BPB to be part of a boot
> sector (at least, it does to me) :)

In the old day's you "created" a BPB that matched the Media-ID byte.
Nowerday's we have Hard-disks, which all have the (generic) value F8, and
that forces us to read the BPB off the disk.


I hope I cleared up any vague points in my question . Now let's see if
anyone knows the answer ...

Regards,
Rudy Wieser

debs

unread,
Nov 16, 2001, 6:34:08 PM11/16/01
to
Hello cyberfolk!

On Fri, 16 Nov 2001 15:52:31 +0100, R.Wieser spake thus:

>> For a FAT partition, you read BPB from the
>> boot sector, and then you determine the size of the partition and some
>> other information based on that.
>
>In the above, when I said HD, I actually tried to say was "any kind of
>storage-media, as small as 360 KB, or as big as 40 GB. Either removable or
>non-removable". In other words : The actual media does not have to be
>accessable by the driver yet (think of PCMCIA-cards, that can be placed or
>removed "hot"), so it's BPB is not known.

OK, I think I understand. Fromw hat you say below, you are using Int
13h to access the disk, so you need to know the structure of the disk
or partition. I understand you saying that in the case of a PCMCIA
drive, the OS doesn't know what storage capacity it is until it is
accessed. Unfortunately, the only way you or the OS and any other
driver can find out that information is by querying the drive to find
out. I dont know how it would be done for PCMCIA, but if it is the
same as for any other FAT format drive, then you would ahve to read
the information from the BPB.

As I dont use DOS interrupts (I'm answering this from alt.lang.asm,
non-OS specific) I don't know off hand if there are DOS calls to check
this information for you. I assume there are, but Im also guessing, as
you are using int 13h to read the disk, that you are not looking for a
way of using to DOS to get the information.

Also, if you are relying on the media descriptor byte to get
information about the drive, that is stored in the BPB, so it has to
be read anyway.

>Yes, I've taken the offset to the logical drive into account. Proove of
>that (for me) is that I can read the Root-directory of the targetted
>(logical) disk.

How did you get the information that told you where the start of the
root directory and it's size are? Based on what you said before, the
BPB is not correct, which implies you are getting the information by
using a DOS call. If that is the case, then you will either have to
find out where the boot sector actually is and read the BPB from that,
or you will need to use DOS calls. I'll be happy to try and help you
track down the problem if I ahve a better idea of where the error is.

It might help to post relevant code for us to try and help with. You
can email it to me if you think it's too much to post here, although
if you can track down the section of code which has problems and post
that here you are likely to get more help with it.

>Well, my specs tell me that DOS tries to determine the geometry of the drive
>from the MEDIA-ID byte. When this NON-IBM -bit is set, DOS will directly
>request the BPB (command-code 2) from the device-driver

The MEDIA-ID byte is only useful for checking the capacity of a floppy
disk. Even then, if you do not know what the size of the drive is (eg
3.5" or 5.25") it could be ambiguous. I'll assume you know know the
disk size for the purpose of this thread, as you aren't posting to an
OS dev group, in which case that won't be a problem :)

Also, as you have stated that you are writing a device driver, DOS
will need to get the infromation from you, you can't rely on the OS
that your device driver is going to serve to be able to tell the
driver what to do. As such, it is up to your driver to get information
and store it somewhere. If it doesn't store it, it will need to get
the inforatmoin every time that it accesses the drive.

>None of the information in the BPB is relevant to my driver : I'm using
>"Large-disk" functions (like INT 13, AH=42h) that look at the drive as
>having a large array of blocks, not heads-tracks-sectors.

If you are writing a device driver, the implication is that you are
writing an interrupt routine (ie, an app which will stay resident and
be called when either an interrupt call is made or an IRQ needs
handling it, depending which you are doing). As such, you can't rely
on being able to use other interrupts to get information needed by the
driver once it is installed.


>
>But DOS uses the BPB information. And I'm not sure if DOS copies the BPB I
>stored into my driver, or just keeps a pointer to it (which forces to keep
>it available at all times).

DOS would probably store the BPB (or at least the needed information
from the BPB) for all drives it has accessed, as they dont take up
much memory. The more drive letters you store the BPB for, the more
memory you would be using, butstoring the BPB is only 25 bytes per
drive, for FAT 12 and 16, making a maximum of 800 bytes, for the 32
drives that DOS can address. Ultimately, it is up to you to decide, if
you are writing the driver. Personally, in the disk driver I am
currently writing, the driver will be sotring data to describe the
parameters of every drive that it can address, because that makes
access faster (if you are copying between two devices, you don't want
to have to look up the data every time you read or write in the same
copy process).


>
>In the old day's you "created" a BPB that matched the Media-ID byte.
>Nowerday's we have Hard-disks, which all have the (generic) value F8, and
>that forces us to read the BPB off the disk.

Ah, you just showed that you knew some of what I posted above :) I'll
leave it in anyway, it might be useful :) Actually, I would dispute
that you could read the MEDIA-ID and know what else is in the BPB, as
the same ID can be used for more than one disk size, based on the size
of the disk. For example, a 720K 3.5" disk and a 1.2M 5.25" disk both
have the ID 0F9h.


>
>I hope I cleared up any vague points in my question . Now let's see if
>anyone knows the answer ...
>

As I said before, if you want to show the code which is causing
trouble, someone might be able to help you more :)

debs
de...@dwiles.nospam.demon.co.uk

Forget the health food. I need all the preservatives I can get.

R.Wieser

unread,
Nov 17, 2001, 8:23:31 AM11/17/01
to
debs <de...@spamfree.net> schreef in berichtnieuws
2h4bvtc139ou0bn52...@4ax.com...
> Hello cyberfolk!

Hello Debs,

> On Fri, 16 Nov 2001 15:52:31 +0100, R.Wieser spake thus:
>

[Snip]

> OK, I think I understand. From what you say below, you are using Int


> 13h to access the disk, so you need to know the structure of the disk
> or partition.

Nope, I don't. The call that I use (INT 13h, AH=42h) regards the drive as a
long string of blocks. No Head-Track-Sector geometry. This way all I have
to do is to add an offset to the requested sector.

> I understand you saying that in the case of a PCMCIA
> drive, the OS doesn't know what storage capacity it is until it is
> accessed. Unfortunately, the only way you or the OS and any other
> driver can find out that information is by querying the drive to find
> out. I dont know how it would be done for PCMCIA, but if it is the

> same as for any other FAT format drive, then you would have to read


> the information from the BPB.

My driver does not need anything from the BPB. DOS hoever does. So it
ask's my driver to return the BPB for the current media (command-code 2).
All I have to do is to read the boot-sector off the logical drive, and
extract the BPB from there.

My question was/is : should this information (the BPB) be static, or will
the information be copied to some other place by DOS, which would mean that
I can erase the structure when the next call comes in ...

> As I dont use DOS interrupts (I'm answering this from alt.lang.asm,
> non-OS specific) I don't know off hand if there are DOS calls to check
> this information for you. I assume there are, but Im also guessing, as
> you are using int 13h to read the disk, that you are not looking for a
> way of using to DOS to get the information.
>
> Also, if you are relying on the media descriptor byte to get
> information about the drive, that is stored in the BPB, so it has to
> be read anyway.

I can't rely on the media-descriptor byte, because it's F8 for (AFAIK) every
hard-disk there is ...

> >Yes, I've taken the offset to the logical drive into account. Proove of
> >that (for me) is that I can read the Root-directory of the targetted
> >(logical) disk.
>
> How did you get the information that told you where the start of the
> root directory and it's size are? Based on what you said before, the
> BPB is not correct, which implies you are getting the information by
> using a DOS call.

A Device-driver does not need that kind of information. It receives
requests for a certain sector, and all it does is to retrieve it.

> If that is the case, then you will either have to
> find out where the boot sector actually is and read the BPB from that,
> or you will need to use DOS calls.

Well, the BPB is allways stored in the first sector of a logical drive, so
it's allways retrievable.

> I'll be happy to try and help you

> track down the problem if I have a better idea of where the error is.

Ehhh ... My question was not to solve an error, but to grasp the validity
of the BPB returned by the "Initialize driver" call (code 0), and if the BPB
returned by the "Create BPB" call should be static, or if it can be erased
when the next call arrives ...

[Snip]

> >Well, my specs tell me that DOS tries to determine the geometry of the
drive
> >from the MEDIA-ID byte. When this NON-IBM -bit is set, DOS will directly
> >request the BPB (command-code 2) from the device-driver
>
> The MEDIA-ID byte is only useful for checking the capacity of a floppy
> disk. Even then, if you do not know what the size of the drive is (eg
> 3.5" or 5.25") it could be ambiguous. I'll assume you know know the
> disk size for the purpose of this thread, as you aren't posting to an
> OS dev group, in which case that won't be a problem :)

I do know the size of the drive, but I do not need to. That information can
be retrieved off the BPB.

> Also, as you have stated that you are writing a device driver, DOS
> will need to get the infromation from you, you can't rely on the OS
> that your device driver is going to serve to be able to tell the
> driver what to do.

But that's exacly what a device-driver is for : accepting requests for
reading/writing sectors, translating them (when using old-style call's) to
the actual drive's geometry, and execute them.

> As such, it is up to your driver to get information
> and store it somewhere. If it doesn't store it, it will need to get
> the inforatmoin every time that it accesses the drive.

In my case (using the newer-style call's) I do not even have to bother with
a translation, an thus do not need any BPB-information. So, my drive has to
do next-to-nothing :-)

> >None of the information in the BPB is relevant to my driver : I'm using
> >"Large-disk" functions (like INT 13, AH=42h) that look at the drive as
> >having a large array of blocks, not heads-tracks-sectors.
>
> If you are writing a device driver, the implication is that you are
> writing an interrupt routine (ie, an app which will stay resident and
> be called when either an interrupt call is made or an IRQ needs
> handling it, depending which you are doing). As such, you can't rely
> on being able to use other interrupts to get information needed by the
> driver once it is installed.

No. My device-driver is not part of any Hardware-interrupt. So I can use
every BIOS call there is.

You can think of it as with INT 21h, AH=02h. This call will write the
contents of DL to the screen. But it uses BIOS-calls (INT 10h) to do that.

> >But DOS uses the BPB information. And I'm not sure if DOS copies the BPB
I
> >stored into my driver, or just keeps a pointer to it (which forces to
keep
> >it available at all times).
>
> DOS would probably store the BPB (or at least the needed information
> from the BPB) for all drives it has accessed, as they dont take up
> much memory. The more drive letters you store the BPB for, the more

> memory you would be using, but storing the BPB is only 25 bytes per


> drive, for FAT 12 and 16, making a maximum of 800 bytes, for the 32
> drives that DOS can address. Ultimately, it is up to you to decide, if
> you are writing the driver.

That's where my problem lies : If only a pointer to the BPB is stored by
DOS, I have no other choice than to keep the information available. If DOS
however copies the information, I can erase it afterwards.

[Snip]

> >In the old day's you "created" a BPB that matched the Media-ID byte.
> >Nowerday's we have Hard-disks, which all have the (generic) value F8, and
> >that forces us to read the BPB off the disk.
>
> Ah, you just showed that you knew some of what I posted above :) I'll
> leave it in anyway, it might be useful :) Actually, I would dispute
> that you could read the MEDIA-ID and know what else is in the BPB, as
> the same ID can be used for more than one disk size, based on the size
> of the disk. For example, a 720K 3.5" disk and a 1.2M 5.25" disk both
> have the ID 0F9h.

So, that's how far back the Media-ID byte lost it's meaning ! But it's
still there. Now that's what I call a Survivor instinct :-)

> >I hope I cleared up any vague points in my question . Now let's see if
> >anyone knows the answer ...
> >
> As I said before, if you want to show the code which is causing
> trouble, someone might be able to help you more :)

Can't help you there (showing the code that causes trouble), because my
"trouble" is not part of the code.

Regards,
Rudy Wieser

debs

unread,
Nov 17, 2001, 3:33:31 PM11/17/01
to
Hello cyberfolk!

On Sat, 17 Nov 2001 14:23:31 +0100, R.Wieser spake thus:

>> OK, I think I understand. From what you say below, you are using Int
>> 13h to access the disk, so you need to know the structure of the disk
>> or partition.
>
>Nope, I don't. The call that I use (INT 13h, AH=42h) regards the drive as a
>long string of blocks. No Head-Track-Sector geometry. This way all I have
>to do is to add an offset to the requested sector.

I think you misunderstood me. I didn't mean you need to know the CHS,
I meant you need to know the starting sector. As you are using BIOS
interrupts rather than DOS interrupts, and you are writing a device
driver, I have to assume that you are WRITING rather than CALLING the
interrupts, as interrupts are not re-entrant unless you write them to
be so specifically. I might still ahve misunderstood you though, so I
have looked up the information relating to this in RBIL, and I am
posting that here. You need to get a copy of that list if you are
going to do much with hardware or interrupts, it is more useful than
the bible for me at times :)

Having just looked through RBIL, I note that int 21h, AH = 32h, DL =
DOS drive number (ie default = 0, A = 1, etc) will return a table of
data pointed to by ES:BX :

<---- Info from Ralf Browns Inerrupt List ---->

Int 21h, AH=32h

Inp.:
AH = 32h
DL = drive number (00h = default, 01h = A:, etc)
Return: AL = status
00h successful
DS:BX -> Drive Parameter Block (DPB) (see #01395) for
specified
drive
FFh invalid or network drive

Notes:
the OS/2 compatibility box supports the DOS 3.3 version of this call
except for the DWORD at offset 12h
this call updates the DPB by reading the disk; the DPB may be accessed
via the DOS list of lists (see #01627 at AH=52h) if disk access is not
desirable.

Table 01395
Format of DOS Drive Parameter Block:
Offset Size Description
00h BYTE drive number (00h = A:, 01h = B:, etc)
01h BYTE unit number within device driver
02h WORD bytes per sector
04h BYTE highest sector number within a cluster
05h BYTE shift count to convert clusters into sectors
06h WORD number of reserved sectors at beginning of drive
08h BYTE number of FATs
09h WORD number of root directory entries
0Bh WORD number of first sector containing user data
0Dh WORD highest cluster number (number of data clusters + 1)
16-bit FAT if greater than 0FF6h, else 12-bit FAT
0Fh BYTE number of sectors per FAT
10h WORD sector number of first directory sector
12h DWORD address of device driver header (see #01646)
16h BYTE media ID byte (see #01356)
17h BYTE 00h if disk accessed, FFh if not
18h DWORD pointer to next DPB
---DOS 2.x---
1Ch WORD cluster containing start of current directory,
0000h=root,
FFFFh = unknown
1Eh 64 BYTEs ASCIZ pathname of current directory for drive
---DOS 3.x---
1Ch WORD cluster at which to start search for free space when
writing
1Eh WORD number of free clusters on drive, FFFFh = unknown
---DOS 4.0-6.0---
0Fh WORD number of sectors per FAT
11h WORD sector number of first directory sector
13h DWORD address of device driver header (see #01646)
17h BYTE media ID byte (see #01356)
18h BYTE 00h if disk accessed, FFh if not
19h DWORD pointer to next DPB
1Dh WORD cluster at which to start search for free space when
writing, usually the last cluster allocated
1Fh WORD number of free clusters on drive, FFFFh = unknown


Table 01627
Format of List of Lists:
Offset Size Description

00h DWORD pointer to first Drive Parameter Block
(see #01395 at AH=32h)
04h DWORD -> first System File Table
(see #01639,#01640,#01641,#01642)
08h DWORD pointer to active CLOCK$ device's header
(most recently loaded driver with CLOCK bit set)
0Ch DWORD pointer to active CON device's header
(most recently loaded driver with STDIN bit set)

<---- end of copied text ---->

Note that I left out a lot of the information that you don't need for
this from the second table.

I snipped the rest of your post, because I don't think my replies
would have helped. I'm a little confused about just what you are
writing, as you call it a device-driver, and to me a device driver is
an interface between the operating system and the hardware, which you
say is not what you are doing. Even the file-system driver needs to
follow the partition chain to find where logical drives are, I can't
think of a higher level driver than that which would be called by DOS.

I hope the above info is more useful than my previous post :)

debs
de...@dwiles.nospam.demon.co.uk

If you can smile when things go wrong, you have someone in mind to blame.

Frank Kotler

unread,
Nov 18, 2001, 1:02:27 AM11/18/01
to
debs wrote:

> Table 01627
> Format of List of Lists:
> Offset Size Description
>
> 00h DWORD pointer to first Drive Parameter Block
> (see #01395 at AH=32h)

This suggests that dos *does* save it's own copy, so Rudy doesn't have
to, no? (if I understood the question...)

Best,
Frank

debs

unread,
Nov 18, 2001, 1:19:29 AM11/18/01
to
Hello cyberfolk!

On Sun, 18 Nov 2001 06:02:27 GMT, Frank Kotler spake thus:

Yes :) I'm still not sure that I understood the question, which is why
I c&ped the section from RBIL for Rudy. It made more sense than trying
to understand, if I could post something which pinpointed what was
being looked for rather than trying to work out if I understood the
question right :)

hmm, not sure how much sense that last paragraph made, still - I know
what I mean :)

R.Wieser

unread,
Nov 18, 2001, 6:47:36 AM11/18/01
to
Frank Kotler <fbko...@ne.mediaone.net> schreef in berichtnieuws
3BF74EE9...@ne.mediaone.net...

Hello Frank,

Well, what's stored here is the DPB, a converted version of the BPB. But it
certainly could mean that I don't have to store it locally. I guess that I
have to just do it (discarding the BPB that is) ans see if my cromputer
crashes ....

Regards,
Rudy Wieser

0 new messages